Unity液压杆、活塞的关联。

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

先给出效果吧(注意下面的连接活塞)

使用前提

首先有这样的一对液压杆,必须在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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值