Skip to content

Commit

Permalink
MonoCurveChain motion
Browse files Browse the repository at this point in the history
  • Loading branch information
Mogoson committed Dec 9, 2022
1 parent 358e703 commit 4b9f40b
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 35 deletions.
Binary file not shown.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions UnityProject/Assets/MGS.Packages/Chain/Demo/Scripts.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*************************************************************************
* Copyright © 2022 Mogoson. All rights reserved.
*------------------------------------------------------------------------
* File : CurveChainDriver.cs
* Description : CurveChainDriver component.
*------------------------------------------------------------------------
* Author : Mogoson
* Version : 0.1.0
* Date : 12/09/2022
* Description : Initial development version.
*************************************************************************/

using UnityEngine;

namespace MGS.Chain.Demo
{
public class CurveChainDriver : MonoBehaviour
{
public MonoCurveChain chain;
public float velocity = 0.15f;

void Update()
{
if (Input.GetKey(KeyCode.P))
{
chain.Drive(velocity * Time.deltaTime);
}
else if (Input.GetKey(KeyCode.N))
{
chain.Drive(-velocity * Time.deltaTime);
}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 12 additions & 12 deletions UnityProject/Assets/MGS.Packages/Chain/Runtime/Chain/MonoChain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public abstract class MonoChain : MonoBehaviour, IChain
[SerializeField]
protected float segment = 0.1f;

/// <summary>
/// Piece length of chain node.
/// </summary>
protected float piece;

/// <summary>
/// Nodes of chain.
/// </summary>
Expand Down Expand Up @@ -95,8 +100,7 @@ public virtual void Rebuild()
return;
}
#endif
var differ = 0f;
var segmentCount = GetSegmentCount(Length, segment, out differ);
var segmentCount = GetSegmentCount(Length, segment, out piece);
while (nodes.Count < segmentCount)
{
AddNodeToLast();
Expand All @@ -107,10 +111,7 @@ public virtual void Rebuild()
RemoveLastNode();
}

foreach (var nodeItem in nodes)
{
AnchorNode(nodeItem, differ);
}
AnchorNodes(nodes);
}

/// <summary>
Expand Down Expand Up @@ -171,22 +172,21 @@ protected void RemoveLastNode()
/// </summary>
/// <param name="length"></param>
/// <param name="segment"></param>
/// <param name="differ"></param>
/// <param name="piece"></param>
/// <returns></returns>
protected int GetSegmentCount(float length, float segment, out float differ)
protected int GetSegmentCount(float length, float segment, out float piece)
{
//AwayFromZero means that 12.5 -> 13
var count = (int)Math.Round(length / segment, MidpointRounding.AwayFromZero);
count = Mathf.Max(count, 1);
differ = length / count;
piece = length / count;
return count;
}

/// <summary>
/// Anchor node to chain.
/// Anchor nodes to chain.
/// </summary>
/// <param name="node"></param>
/// <param name="differ"></param>
protected abstract void AnchorNode(Node node, float differ);
protected abstract void AnchorNodes(List<Node> nodes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*************************************************************************/

using MGS.Curve;
using System.Collections.Generic;
using UnityEngine;

namespace MGS.Chain
Expand All @@ -31,6 +32,11 @@ public class MonoCurveChain : MonoChain
/// </summary>
protected IMonoCurve curve;

/// <summary>
/// Current motion of chain.
/// </summary>
protected float motion;

/// <summary>
/// Rebuild chain base curve.
/// </summary>
Expand All @@ -41,6 +47,19 @@ public virtual void Rebuild(IMonoCurve curve)
Rebuild();
}

/// <summary>
/// Drive the chain.
/// </summary>
/// <param name="velocity">Linear velocity.</param>
public virtual void Drive(float velocity)
{
motion += velocity;
foreach (var node in nodes)
{
TowNodeAlongCurve(node, motion);
}
}

/// <summary>
/// [MESSAGE] On mono curve rebuild.
/// </summary>
Expand All @@ -51,23 +70,45 @@ private void OnMonoCurveRebuild(IMonoCurve curve)
}

/// <summary>
/// Anchor node to chain.
/// Anchor nodes to chain.
/// </summary>
/// <param name="node"></param>
protected override void AnchorNodes(List<Node> nodes)
{
TowNodesAlongCurve(nodes, 0);
}

/// <summary>
/// Tow nodes along curve.
/// </summary>
/// <param name="nodes"></param>
/// <param name="motion"></param>
protected void TowNodesAlongCurve(List<Node> nodes, float motion)
{
foreach (var node in nodes)
{
TowNodeAlongCurve(node, motion);
}
}

/// <summary>
/// Tow node along center curve.
/// </summary>
/// <param name="node"></param>
/// <param name="differ"></param>
protected override void AnchorNode(Node node, float differ)
/// <param name="motion"></param>
protected virtual void TowNodeAlongCurve(Node node, float motion)
{
var t = node.ID * differ;
var nodePos = curve.Evaluate(t);
var len = (motion + node.ID * piece) % Length;
var nodePos = curve.Evaluate(len);

var dt = (node.ID + 1) * differ;
var deltaPos = curve.Evaluate(dt);
var nextLen = (motion + (node.ID + 1) * piece) % Length;
var nextPos = curve.Evaluate(nextLen);

var secant = (deltaPos - nodePos).normalized;
var secant = (nextPos - nodePos).normalized;
var worldUp = Vector3.Cross(secant, transform.up);

node.transform.position = nodePos;
node.transform.LookAt(deltaPos, worldUp);
node.transform.LookAt(nextPos, worldUp);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ protected virtual void Start() { }
/// </summary>
protected override void RebuildCollider(IMonoCurve curve)
{
var differ = 0f;
Segments = MonoCurveUtility.GetSegmentCount(curve, segment, out differ);
var piece = 0f;
Segments = MonoCurveUtility.GetSegmentCount(curve, segment, out piece);
RequireCapsules(Segments);
SetCapsules(curve, Segments, differ);
SetCapsules(curve, Segments, piece);
}

/// <summary>
Expand All @@ -77,21 +77,21 @@ protected override void ClearCollider()
/// </summary>
/// <param name="curve"></param>
/// <param name="segments"></param>
/// <param name="differ"></param>
protected virtual void SetCapsules(IMonoCurve curve, int segments, float differ)
/// <param name="piece"></param>
protected virtual void SetCapsules(IMonoCurve curve, int segments, float piece)
{
for (int i = 0; i < segments; i++)
{
var node = colliderGroup.GetChild(i);
node.position = curve.Evaluate((i + 0.5f) * differ);
var tangent = (curve.Evaluate((i + 1) * differ) - curve.Evaluate(i * differ));
node.position = curve.Evaluate((i + 0.5f) * piece);
var tangent = (curve.Evaluate((i + 1) * piece) - curve.Evaluate(i * piece));
node.LookAt(node.position + tangent);

var capsule = node.GetComponent<CapsuleCollider>();
capsule.enabled = enabled;
capsule.center = Vector3.zero;
capsule.direction = 2;
capsule.height = differ + radius * 2;
capsule.height = piece + radius * 2;
capsule.radius = radius;
capsule.isTrigger = isTrigger;
capsule.material = material;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ public override void Rebuild(IMonoCurve curve)
return;
}

var differ = 0f;
Segments = MonoCurveUtility.GetSegmentCount(curve, segment, out differ) + 1;
var piece = 0f;
Segments = MonoCurveUtility.GetSegmentCount(curve, segment, out piece) + 1;
SetVertexCount(lineRenderer, Segments);
for (int i = 0; i < Segments; i++)
{
lineRenderer.SetPosition(i, curve.LocalEvaluate(i * differ));
lineRenderer.SetPosition(i, curve.LocalEvaluate(i * piece));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ public sealed class MonoCurveUtility
/// </summary>
/// <param name="curve"></param>
/// <param name="segment"></param>
/// <param name="differ">Differentiation.</param>
/// <param name="piece"></param>
/// <returns>Detail count of mono curve.</returns>
public static int GetSegmentCount(IMonoCurve curve, float segment, out float differ)
public static int GetSegmentCount(IMonoCurve curve, float segment, out float piece)
{
//AwayFromZero means that 12.5 -> 13
var count = (int)Math.Round(curve.Length / segment, MidpointRounding.AwayFromZero);
count = Mathf.Max(count, 1);
differ = curve.Length / count;
piece = curve.Length / count;
return count;
}
}
Expand Down

0 comments on commit 4b9f40b

Please sign in to comment.