免责声明:此功能代码并不是我所写,而是公司老项目中的源码,只用来学习,方便运用和记录。(有大佬看得懂可以出来解读一下代码)
先给出效果吧(注意下面的连接活塞):

使用前提:
首先有这样的一对液压杆,必须在3dmax当中把模型分离出来,并且轴设置为模型的旋转点如图。
在Unity当中如何使用代码:
首先创建两个代码:RockerJoint,Mechanism(源码在最后)
Mechanism代码不用挂载,RockerJoint需要挂载,
在unity当中,首先复制这一对活塞,并将复制出来的物体设置为活塞的父物体,当然父物体身上的MeshRenderer之类的模型组件删除,因为父物体是用来挂载RockerJoint代码并不需要有物体。如图
接着你就会发现你的物体会一个飞到上面一个飞到下面,这是代码问题,看得懂的可以解决一下

这里我们需要手动对齐了,旋转模型物体的轴,因为你是拉不动父物体的轴的,使他们对齐。

最后在父物体中赋值代码,赋值方法为交叉赋值,第一个父物体赋值第二个父物体,第二个父物体赋值第一个父物体,
到这里大功告成
源码:
RockerJoint:
namespace Developer.Mechinery
{
using UnityEngine;
[AddComponentMenu("Developer/Mechinery/RockerJoint")]
[ExecuteInEditMode]
public class RockerJoint : RockerMechanism
{
#region Protected Method
//#if UNITY_EDITOR
/// <summary>
/// Rock rocker on editor mode.
/// </summary>
[ContextMenu("Apply")]
protected virtual void Update()
{
DriveMechanism();
}//U...()_end
//#endif
#endregion
#region Public Method
/// <summary>
/// Drive the mechanism.
/// </summary>
public override void DriveMechanism ()
{
transform.LookAt(rockJoint, transform.up);
}//DriveM...()_end
#endregion
}//Class_end
}//namespace_end
Mechanism:
namespace Developer.Mechinery
{
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Telescopic Mechanism's State.//伸缩机的状态
/// </summary>
public enum TelescopicState
{
Shrink, Drift, Extend
}//enum_end
/// <summary>
/// Mechanism.
/// </summary>
public abstract class Mechanism : MonoBehaviour
{
/// <summary>
/// Drive the mechanism.
/// </summary>
/// <param name="speedControl">Speed control.</param>
public abstract void DriveMechanism(float speedControl);
}//class_end
/// <summary>
/// Crank Mechanism.
/// </summary>
public abstract class CrankMechanism : RockerLockLinkMechanism
{
#region Property and Field用于描述曲柄机构的状态相关信息
/// <summary>
/// Crank drive speed.曲柄的驱动速度
/// </summary>
public float speed = 0.0f;
/// <summary>
/// Current angle of crank.当前角度
/// </summary>
public float angle { protected set; get; }
/// <summary>
/// Start eulerAngles.初始欧拉角
/// </summary>
protected Vector3 eA = Vector3.zero;
#endregion
#region Protected Method
/// <summary>
/// Save angle.
/// </summary>
protected override void Awake()
{
base.Awake();
//Save start angles.
eA = transform.localRotation.eulerAngles;
angle = eA.x;
}//Awake()_end
/// <summary>
/// Rotate the crank by angle.
/// </summary>
protected virtual void DriveCrank()
{
transform.localRotation = Quaternion.Euler(angle, eA.y, eA.z);
DriveRockers();
}//DriveArm()_end
#endregion
}//class_end
/// <summary>
/// Crank Link Mechanism.
/// </summary>
public abstract class CrankLinkMechanism : Mechanism
{
#region Property and Field
/// <summary>
/// Power crank.关联的曲柄机构
/// </summary>
public CrankMechanism crank;
/// <summary>
/// Gearing link bar.
/// </summary>
public RockerMechanism linkBar;
/// <summary>
/// Dead lock state.
/// </summary>
public bool Lock { protected set; get; }
/// <summary>
/// Drive direction.
/// </summary>
public bool positive { protected set; get; }
#endregion
#region Protected Method
/// <summary>
/// Get link bar position base mechanism root.
/// </summary>
/// <returns>Local position.</returns>
protected virtual Vector3 GetNLP()
{
var cp = crank.transform.parent;
var lp = linkBar.transform.position;
return cp.InverseTransformPoint(lp);
}//GetLP()_end
/// <summary>
/// Drive bars.
/// </summary>
protected abstract void DriveBars();
#endregion
#region Public Method
/// <summary>
/// Drive the mechanism.
/// </summary>
/// <param name="speedControl">Speed control.</param>
public override void DriveMechanism(float speedControl)
{
if (crank.speed * speedControl >= 0.0f)
{
if (Lock && positive)
return;
positive = true;
}
else
{
if (Lock && !positive)
return;
positive = false;
}//if()_end
crank.DriveMechanism(speedControl);
DriveBars();
}//DriveM...()_end
#endregion
}//class_end
/// <summary>
/// Telescopic Joint Mechanism.
/// </summary>
public abstract class TelescopicJointMechanism : RockerLockLinkMechanism
{
#region Property and Field
/// <summary>
/// Stroke of joint.
/// </summary>
public float stroke = 0.0f;
/// <summary>
/// Drive speed of joint.
/// </summary>
public float speed = 0.0f;
/// <summary>
/// Displacement of joint.
/// </summary>
public float d { protected set; get; }
/// <summary>
/// Telescopic joint state.
/// </summary>
public TelescopicState tState { protected set; get; }
/// <summary>
/// Start position of joint.
/// </summary>
protected Vector3 p = Vector3.zero;
#endregion
#region Protected Method
protected override void Awake()
{
base.Awake();
p = transform.localPosition;
tState = TelescopicState.Shrink;
}//Awake()_end
/// <summary>
/// Drive joint.
/// </summary>
protected virtual void DriveJoint()
{
tState = TelescopicState.Drift;
transform.localPosition = p + Vector3.forward * d;
DriveRockers();
}//DriveJoint()_end
#endregion
}//class_end
/// <summary>
/// Telescopic Arm Mechanism.
/// </summary>
public abstract class TelescopicArmMechanism : Mechanism
{
#region Property and Field
/// <summary>
/// Telescopic joint of arm.
/// </summary>
public List<TelescopicJointMechanism> tJoints;
#endregion
}//class_end
/// <summary>
/// Rocker Mechanism.
/// </summary>
public abstract class RockerMechanism : MonoBehaviour
{
#region Property and Field
/// <summary>
/// Rocker look at joint.
/// </summary>
public Transform rockJoint;
#endregion
#region Public method
/// <summary>
/// Drive the mechanism.
/// </summary>
public abstract void DriveMechanism ();
#endregion
}//class_end
/// <summary>
/// Rocker Lock Mechanism.
/// </summary>
public abstract class RockerLockMechanism : MonoBehaviour
{
#region Property and Field
/// <summary>
/// Min stroke of the rocker.
/// </summary>
public float minStroke = 0.0f;
/// <summary>
/// Max stroke of the rocker.
/// </summary>
public float maxStroke = 10.0f;
/// <summary>
/// Rocker's lock state.
/// </summary>
public bool isLock
{
get
{
var currentDis = GetDistance();
return currentDis <= minStroke || currentDis >= maxStroke;
}//get_end
}//isLock_end
/// <summary>
/// Lock target roker joint.
/// </summary>
protected RockerJoint rJoint;
#endregion
#region Protected Method
/// <summary>
/// Save reference.
/// </summary>
protected virtual void Awake()
{
rJoint = GetComponent<RockerJoint>();
}//Awake()_end
/// <summary>
/// Get distance from this transform to rJoint.rockJoint transform.
/// </summary>
/// <returns>Distance</returns>
protected virtual float GetDistance()
{
return Vector3.Distance(transform.position, rJoint.rockJoint.position);
}//Get...()_end
#endregion
}//class_end
/// <summary>
/// Rocker Lock Link Mechanism.
/// </summary>
public abstract class RockerLockLinkMechanism : Mechanism
{
#region Property and Field
/// <summary>
/// Rockers that drive by mechanism.
/// </summary>
public List<RockerMechanism> rockers;
/// <summary>
/// Rocker locks in this mechanism.
/// </summary>
protected List<RockerLockMechanism> rLocks;
/// <summary>
/// Record lock angle.
/// </summary>
protected float lockRecord = 0.0f;
#endregion
#region Protected Method
/// <summary>
/// Find rocker locks.
/// </summary>
protected virtual void Awake()
{
FindRockerLocks();
}//Awake()_end
/// <summary>
/// find rocker locks in this mechanism.
/// </summary>
protected virtual void FindRockerLocks()
{
//Find rocker locks.
rLocks = new List<RockerLockMechanism>();
foreach (var rocker in rockers)
{
var rlock = rocker.GetComponent<RockerLockMechanism>();
if (rlock)
rLocks.Add(rlock);
}//foreach()_end
}//Find...()_end
/// <summary>
/// Check rockers's lock state.
/// </summary>
/// <returns>Return true if one of the rockers is lock.</returns>
protected virtual bool CheckRockersLock()
{
foreach (var rL in rLocks)
{
if (rL.isLock)
return true;
}//foreach()_end
return false;
}//Check...()_end
/// <summary>
/// Drive the rockers that join at this mechanism.
/// </summary>
protected virtual void DriveRockers()
{
//no rocker to drive.
if (rockers == null || rockers.Count == 0)
return;
foreach (var r in rockers)
{
r.DriveMechanism();
}
}//DriveRockers()_end
#endregion
}//class_end
}//namespace_end

被折叠的 条评论
为什么被折叠?



