/** * @brief Instantiates a new prefab in a deterministic way. * * @param prefab GameObject's prefab to instantiate. * @param position Position to place the new GameObject. * @param rotation Rotation to set in the new GameObject. **/ public static GameObject SyncedInstantiate(GameObject prefab, FPVector position, FPQuaternion rotation) { if (instance != null /*&& instance.lockstep != null*/) { GameObject go = GameObject.Instantiate(prefab, position.ToVector(), rotation.ToQuaternion()) as GameObject; MonoBehaviour[] monoBehaviours = go.GetComponentsInChildren <MonoBehaviour>(); for (int index = 0, length = monoBehaviours.Length; index < length; index++) { MonoBehaviour bh = monoBehaviours[index]; if (bh is IFrameSyncBehaviour) { instance.mapManagedBehaviors.Add(new KeyValuePair <IFrameSyncBehaviour, FrameSyncManagedBehaviour>( (IFrameSyncBehaviour)bh, instance.NewManagedBehavior((IFrameSyncBehaviour)bh) )); } } InitializeGameObject(go, position, rotation); return(go); } return(null); }
public static Quaternion ToUnityQuaternion(this FPQuaternion r) { Quaternion q; q.x = r.X.AsFloat; q.y = r.Y.AsFloat; q.z = r.Z.AsFloat; q.w = r.W.AsFloat; // calculate square magnitude var sqr = (q.x * q.x) + (q.y * q.y) + (q.z + q.z) + (q.w * q.w); if (Mathf.Approximately(sqr, 0)) { return(Quaternion.identity); } // re-normalize quaternion var fac = 1f / sqr; q.x *= fac; q.y *= fac; q.z *= fac; q.w *= fac; return(q); }
public static FPMatrix4x4 TRS(FPVector translation, FPQuaternion rotation, FPVector scale) { FPMatrix4x4 result; TRS(translation, rotation, scale, out result); return(result); }
public static FPMatrix4x4 Rotate(FPQuaternion quaternion) { FPMatrix4x4 result; FPMatrix4x4.Rotate(ref quaternion, out result); return(result); }
/// <summary> /// Creates a JMatrix representing an orientation from a quaternion. /// </summary> /// <param name="quaternion">The quaternion the matrix should be created from.</param> /// <param name="result">JMatrix representing an orientation.</param> public static void Rotate(ref FPQuaternion quaternion, out FPMatrix4x4 result) { // Precalculate coordinate products FP x = quaternion.x * 2; FP y = quaternion.y * 2; FP z = quaternion.z * 2; FP xx = quaternion.x * x; FP yy = quaternion.y * y; FP zz = quaternion.z * z; FP xy = quaternion.x * y; FP xz = quaternion.x * z; FP yz = quaternion.y * z; FP wx = quaternion.w * x; FP wy = quaternion.w * y; FP wz = quaternion.w * z; // Calculate 3x3 matrix from orthonormal basis result.M11 = FP.One - (yy + zz); result.M21 = xy + wz; result.M31 = xz - wy; result.M41 = FP.Zero; result.M12 = xy - wz; result.M22 = FP.One - (xx + zz); result.M32 = yz + wx; result.M42 = FP.Zero; result.M13 = xz + wy; result.M23 = yz - wx; result.M33 = FP.One - (xx + yy); result.M43 = FP.Zero; result.M14 = FP.Zero; result.M24 = FP.Zero; result.M34 = FP.Zero; result.M44 = FP.One; }
public static FPMatrix CreateFromQuaternion(FPQuaternion quaternion) { FPMatrix result; FPMatrix.CreateFromQuaternion(ref quaternion, out result); return(result); }
private static void InitializeGameObject(GameObject go, FPVector position, FPQuaternion rotation) { ICollider[] tsColliders = go.GetComponentsInChildren <ICollider>(); if (tsColliders != null) { for (int index = 0, length = tsColliders.Length; index < length; index++) { PhysicsManager.instance.AddBody(tsColliders[index]); } } FPTransform rootFPTransform = go.GetComponent <FPTransform>(); if (rootFPTransform != null) { rootFPTransform.Initialize(); rootFPTransform.position = position; rootFPTransform.rotation = rotation; } FPTransform[] FPTransforms = go.GetComponentsInChildren <FPTransform>(); if (FPTransforms != null) { for (int index = 0, length = FPTransforms.Length; index < length; index++) { FPTransform FPTransform = FPTransforms[index]; if (FPTransform != rootFPTransform) { FPTransform.Initialize(); } } } FPTransform2D rootFPTransform2D = go.GetComponent <FPTransform2D>(); if (rootFPTransform2D != null) { rootFPTransform2D.Initialize(); rootFPTransform2D.position = new FPVector2(position.x, position.y); rootFPTransform2D.rotation = rotation.ToQuaternion().eulerAngles.z; } FPTransform2D[] FPTransforms2D = go.GetComponentsInChildren <FPTransform2D>(); if (FPTransforms2D != null) { for (int index = 0, length = FPTransforms2D.Length; index < length; index++) { FPTransform2D FPTransform2D = FPTransforms2D[index]; if (FPTransform2D != rootFPTransform2D) { FPTransform2D.Initialize(); } } } }
public static FPMatrix CreateFromYawPitchRoll(Fix64 yaw, Fix64 pitch, Fix64 roll) { FPMatrix matrix; FPQuaternion quaternion; FPQuaternion.CreateFromYawPitchRoll(yaw, pitch, roll, out quaternion); CreateFromQuaternion(ref quaternion, out matrix); return(matrix); }
public void Clone(RigidBody rb) { this.marker = rb.marker; this.affectedByGravity = rb.affectedByGravity; this.boundingBox = rb.boundingBox; this.internalIndex = rb.internalIndex; this.inverseMass = rb.inverseMass; this.isColliderOnly = rb.isColliderOnly; this.isStatic = rb.isStatic; this.isKinematic = rb.isKinematic; this.sweptDirection = rb.sweptDirection; this.position = rb.Position; this.orientation = rb.Orientation; this.linearVelocity = rb.LinearVelocity; this.angularVelocity = rb.AngularVelocity; this.inertia = rb.Inertia; this.invInertia = rb.InverseInertia; this.invInertiaWorld = rb.InverseInertiaWorld; this.invOrientation = rb.invOrientation; this.force = rb.Force; this.torque = rb.Torque; this.shapeClone = poolGenericShapeClone.GetNew(); this.shapeClone.Clone(rb.Shape); this.connections.Clear(); for (index = 0, length = rb.connections.Count; index < length; index++) { this.connections.Add(rb.connections[index]); } this.constraints.Clear(); for (index = 0, length = rb.constraints.Count; index < length; index++) { this.constraints.Add(rb.constraints[index]); } this.isActive = rb.IsActive; this.inactiveTime = rb.inactiveTime; this.marker = rb.marker; this.disabled = rb.disabled; this.freezeConstraint = rb._freezeConstraints; this._freezePosition = rb._freezePosition; this._freezeRotation = rb._freezeRotation; this._freezeRotationQuat = rb._freezeRotationQuat; this.prevKinematicGravity = rb.prevKinematicGravity; this.linearDrag = rb.linearDrag; this.angularDrag = rb.angularDrag; this.staticFriction = rb.staticFriction; this.restitution = rb.restitution; }
/** * @brief Instantiates a new prefab in a deterministic way. * * @param prefab GameObject's prefab to instantiate. * @param position Position to place the new GameObject. * @param rotation Rotation to set in the new GameObject. **/ public static GameObject SyncedInstantiate(GameObject prefab, FPVector position, FPQuaternion rotation) { if (instance != null /*&& instance.lockstep != null*/) { GameObject go = GameObject.Instantiate(prefab, position.ToVector(), rotation.ToQuaternion()) as GameObject; AddSyncBehaviour(go); InitializeGameObject(go, position, rotation); return(go); } return(null); }
internal void PostStep() { if (_freezeConstraints > 0) { bool freezePosX = (_freezeConstraints & FPRigidBodyConstraints.FreezePositionX) == FPRigidBodyConstraints.FreezePositionX; bool freezePosY = (_freezeConstraints & FPRigidBodyConstraints.FreezePositionY) == FPRigidBodyConstraints.FreezePositionY; bool freezePosZ = (_freezeConstraints & FPRigidBodyConstraints.FreezePositionZ) == FPRigidBodyConstraints.FreezePositionZ; if (freezePosX) { position.x = _freezePosition.x; } if (freezePosY) { position.y = _freezePosition.y; } if (freezePosZ) { position.z = _freezePosition.z; } bool freezeRotX = (_freezeConstraints & FPRigidBodyConstraints.FreezeRotationX) == FPRigidBodyConstraints.FreezeRotationX; bool freezeRotY = (_freezeConstraints & FPRigidBodyConstraints.FreezeRotationY) == FPRigidBodyConstraints.FreezeRotationY; bool freezeRotZ = (_freezeConstraints & FPRigidBodyConstraints.FreezeRotationZ) == FPRigidBodyConstraints.FreezeRotationZ; if (freezeRotX || freezeRotY || freezeRotZ) { FPQuaternion q = FPQuaternion.CreateFromMatrix(Orientation); if (freezeRotX) { q.x = _freezeRotationQuat.x; } if (freezeRotY) { q.y = _freezeRotationQuat.y; } if (freezeRotZ) { q.z = _freezeRotationQuat.z; } q.Normalize(); Orientation = FPMatrix.CreateFromQuaternion(q); } } }
private void IntegrateCallback(object obj) { RigidBody body = obj as RigidBody; FPVector temp; FPVector.Multiply(ref body.linearVelocity, timestep, out temp); FPVector.Add(ref temp, ref body.position, out body.position); if (!(body.isParticle)) { //exponential map FPVector axis; FP angle = body.angularVelocity.magnitude; if (angle < FP.EN3) { // use Taylor's expansions of sync function // axis = body.angularVelocity * (FP.Half * timestep - (timestep * timestep * timestep) * (0.020833333333f) * angle * angle); FPVector.Multiply(ref body.angularVelocity, (FP.Half * timestep - (timestep * timestep * timestep) * (2082 * FP.EN6) * angle * angle), out axis); } else { // sync(fAngle) = sin(c*fAngle)/t FPVector.Multiply(ref body.angularVelocity, (FP.Sin(FP.Half * angle * timestep) / angle), out axis); } FPQuaternion dorn = new FPQuaternion(axis.x, axis.y, axis.z, FP.Cos(angle * timestep * FP.Half)); FPQuaternion ornA; FPQuaternion.CreateFromMatrix(ref body.orientation, out ornA); FPQuaternion.Multiply(ref dorn, ref ornA, out dorn); dorn.Normalize(); FPMatrix.CreateFromQuaternion(ref dorn, out body.orientation); } body.linearVelocity *= 1 / (1 + timestep * body.linearDrag); body.angularVelocity *= 1 / (1 + timestep * body.angularDrag); /*if ((body.Damping & RigidBody.DampingType.Linear) != 0) * FPVector.Multiply(ref body.linearVelocity, currentLinearDampFactor, out body.linearVelocity); * * if ((body.Damping & RigidBody.DampingType.Angular) != 0) * FPVector.Multiply(ref body.angularVelocity, currentAngularDampFactor, out body.angularVelocity);*/ body.Update(); if (CollisionSystem.EnableSpeculativeContacts || body.EnableSpeculativeContacts) { body.SweptExpandBoundingBox(timestep); } }
/// <summary> /// 改变朝向,改变forward的朝向跟摄像机的朝向一样 /// </summary> /// <param name="forward"></param> public void ChangeAvatarForward(FPVector toForward) { JoystickAngle = 90; if (AvatarForm == E_AvatarForm.PERSON_STATE) { _ufpTransformChildObj.ChangeForward(toForward); return; } RaycastHit _groundHit; _characterMotionObj.RayGroundInfo(out _groundHit); FPVector _fpNormal = _ufpTransformChildObj.ChangeVec3ToTSVec(_groundHit.normal); if (_groundHit.normal == Vector3.up) { _ufpTransformChildObj.ChangeForward(toForward); // _childObj.forward = toForward; JoystickAngle = 90; return; } else { FPVector left = FPVector.Cross(toForward, _fpNormal); //切线 FPVector newForward = FPVector.Cross(_fpNormal, left); if (_fpNormal == FPVector.zero) { Debug.Log("forward:::" + toForward); return; } FPQuaternion newRotation = FPQuaternion.LookRotation(newForward, _fpNormal); U_FPTransform ComMoveTransform = ComMoveFollowObj.GetFPTransform(); FPQuaternion comObject = new FPQuaternion(ComMoveTransform.rotation.x, ComMoveTransform.rotation.y, ComMoveTransform.rotation.z, ComMoveTransform.rotation.w); // ComMoveFollowObj.transform.rotation = newRotation; ComMoveTransform.SetRotation(newRotation); FPVector comForward = ComMoveTransform.forward; FPVector childForward = _ufpTransformChildObj.forward; FP DragAngle = FPVector.Angle(comForward, childForward); DragAngle = FPMath.Sign(FPVector.Cross(childForward, comForward).y) * DragAngle; ChangeAvaterForward(DragAngle); //改变对象的旋转数值 ComMoveTransform.SetRotation(comObject); //恢复摄像机原来的rotation数值 } }
/// <summary> /// 跨面操作 /// </summary> /// <param name="forward"></param> /// <param name="position"></param> /// <param name="normal"></param> public void FitSurfaceParent(FPVector forward, FPVector position, FPVector normal) { FPVector left = FPVector.Cross(forward, normal); //切线 FPVector newForward = FPVector.Cross(normal, left); if (normal == FPVector.zero) { Debug.Log("forward:::" + forward); return; } FPQuaternion newRotation = FPQuaternion.LookRotation(newForward, normal); UpdateRotation(newRotation); UpdatePosition(position); //Debug.Log(" _ufpTransform.up::" + _ufpTransform.up.ToVector() + "newRotation::" + newRotation.ToQuaternion() // + ",forward::" + forward.ToVector() + ",normal:::" + normal.ToVector() + ",newForward::" + newForward.ToVector()); }
public override void PostStep() { FPVector pos = Body1.Position; pos.z = 0; Body1.Position = pos; FPQuaternion q = FPQuaternion.CreateFromMatrix(Body1.Orientation); q.Normalize(); q.x = 0; q.y = 0; if (freezeZAxis) { q.z = 0; } Body1.Orientation = FPMatrix.CreateFromQuaternion(q); if (Body1.isStatic) { return; } FPVector vel = Body1.LinearVelocity; vel.z = 0; Body1.LinearVelocity = vel; FPVector av = Body1.AngularVelocity; av.x = 0; av.y = 0; if (freezeZAxis) { av.z = 0; } Body1.AngularVelocity = av; }
/// <summary> /// Creates a JMatrix representing an orientation from a quaternion. /// </summary> /// <param name="quaternion">The quaternion the matrix should be created from.</param> /// <param name="result">JMatrix representing an orientation.</param> public static void CreateFromQuaternion(ref FPQuaternion quaternion, out FPMatrix result) { Fix64 num9 = quaternion.x * quaternion.x; Fix64 num8 = quaternion.y * quaternion.y; Fix64 num7 = quaternion.z * quaternion.z; Fix64 num6 = quaternion.x * quaternion.y; Fix64 num5 = quaternion.z * quaternion.w; Fix64 num4 = quaternion.z * quaternion.x; Fix64 num3 = quaternion.y * quaternion.w; Fix64 num2 = quaternion.y * quaternion.z; Fix64 num = quaternion.x * quaternion.w; result.M11 = Fix64.One - (2 * (num8 + num7)); result.M12 = 2 * (num6 + num5); result.M13 = 2 * (num4 - num3); result.M21 = 2 * (num6 - num5); result.M22 = Fix64.One - (2 * (num7 + num9)); result.M23 = 2 * (num2 + num); result.M31 = 2 * (num4 + num3); result.M32 = 2 * (num2 - num); result.M33 = Fix64.One - (2 * (num8 + num9)); }
private void OnCollisionEnter(Collision collision) { if (!bMoveFlag && _ufpTransform) { RaycastHit _groundHit; if (Physics.Raycast(RayPointObj.transform.position, -Vector3.up, out _groundHit, GroundRayLength)) //悬空 { FPVector fpNormal = _ufpTransform.ChangeVec3ToTSVec(_groundHit.normal); if (_ufpTransform.up == fpNormal) { return; } FP angle = FPVector.Angle(_ufpTransform.up, fpNormal); FPVector fpPoint = _ufpTransform.ChangeVec3ToTSVec(_groundHit.point); FPVector newCrossVec3 = FPVector.Cross(_ufpTransform.up, fpNormal); if (_childObj) { FPVector forward = FPQuaternion.AngleAxis(angle, newCrossVec3) * (_ufpTransform.forward); FitSurfaceParent(forward, fpPoint, fpNormal); } } } }
/** * @brief Instantiates a new prefab in a deterministic way. * * @param prefab GameObject's prefab to instantiate. * @param position Position to place the new GameObject. * @param rotation Rotation to set in the new GameObject. **/ public static GameObject SyncedInstantiate(GameObject prefab, FPVector2 position, FPQuaternion rotation) { return(SyncedInstantiate(prefab, new FPVector(position.x, position.y, 0), rotation)); }
public static Quaternion ToQuaternion(this FPMatrix jMatrix) { return(FPQuaternion.CreateFromMatrix(jMatrix).ToQuaternion()); }
public static Quaternion ToQuaternion(this FPQuaternion rot) { return(new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.w)); }
public void Update() { if (_destVector != FPVector.zero) { float disData = Vector3.Distance(transform.position, _ufpTransform.position.ToVector()); FP fixDistan = MoveSpeed * Time.deltaTime; if (disData <= fixDistan) { UpdatePosition(_ufpTransform.position); UpdateRotation(_ufpTransform.rotation); // Debug.Log("======>arrived_____arrived_____arrived_____arrived_____arrived:::" + _ufpTransform.position); } else { transform.position += (_childObj.forward * fixDistan).ToVector(); // Debug.Log("======>_ufpTransform.position_OnLine:::"+ _ufpTransform.position); } } if (_destRoundData != 0) { FP angleData = _destRoundData - _roundData; FP _tempData = RotationSpeed * MoveSpeed * Time.deltaTime; //Debug.Log("======>angleData:::" + angleData.AsFloat() // + ",_tempData::" + _tempData.AsFloat() + ",_destRoundData::"+ _destRoundData); if (FPMath.Abs(angleData) <= FPMath.Abs(_tempData)) { UpdatePosition(_ufpTransform.position); UpdateRotation(_ufpTransform.rotation); _roundData = _destRoundData; //Debug.Log("======>arrived_____round_____arrived_____round_____arrived:::" + _ufpTransform.position // + ",childObj.forward::" + _childObj.forward + ",childObj.forward.toVector3::" + _childObj.forward.ToVector()); } else { transform.RotateAround(_center.ToVector(), transform.up, _tempData.AsFloat()); _roundData += _tempData; Debug.Log("======>_ufpTransform.round_round_OnLine:::" + _ufpTransform.position + ",_ufpTransform.position.toVector3::" + _ufpTransform.position // + ", ufpTransform.rotation:::" + _ufpTransform.rotation // + ",_ufpTransform.rotation.toVector()::" + _ufpTransform.rotation.ToQuaternion() + ",childObj.forward::" + _childObj.forward + ",childObj.forward.toVector3::" + _childObj.forward.ToVector()); } } RaycastHit hitInfo; bool bExitBarrier = (RayBarrierInfo(_childObj.forward.ToVector(), out hitInfo)); RaycastHit _groundHit; RaycastHit _hitInfo; if (bJumpFlag) //处理跳跃 { if (!bJumpArtFlag) //表示第一次开始跳跃 { if (!RayGroundInfo(out _groundHit, true)) { bJumpArtFlag = true; } } else { if (RayGroundInfo(out _groundHit, true)) { bJumpFlag = false; bJumpArtFlag = false; return; } } _jumpSpeed = _jumpSpeed - g * FrameSyncManager.DeltaTime; //垂直上的初速度随时间的改变 _ufpTransform.Translate(FPVector.up * _jumpSpeed * FrameSyncManager.DeltaTime, Space.World); //垂直上的运动 UpdateRotation(_ufpTransform.rotation); UpdatePosition(_ufpTransform.position); //transform.Translate(Vector3.up * _jumpSpeed * FrameSyncManager.DeltaTime, Space.World);//垂直上的运动 //if (_jumpSpeed < 0 && RayGroundInfo(out _groundHit, true)) //增加防止坠落的操作 //{ // transform/*.parent*/.position = new Vector3(transform/*.parent*/.position.x, _groundHit.point.y, transform/*.parent*/.position.z); // bJumpFlag = false; // bJumpArtFlag = false; // return; //} if (bMoveFlag) { _ufpTransform.Translate(_childObj.forward * MoveSpeed * FrameSyncManager.DeltaTime, Space.World);//水平上的运动 UpdateRotation(_ufpTransform.rotation); UpdatePosition(_ufpTransform.position); // transform.Translate(_childObj.forward.ToVector() * (MoveSpeed/** _frameEntityObj.SpeedRate*/).AsFloat() * Time.fixedDeltaTime, Space.World);//水平上的运动 } return; } else if (!RayGroundInfo(out _groundHit) && !RayBarrierInfo(_childObj.forward.ToVector(), out _hitInfo) && _bHasSpeed)//空中调整角度 { //Debug.Log("_childObj.forward.ToVector():::" + _childObj.forward.ToVector() // + ",,,,data__ufpTransform.up::" + _ufpTransform.up.ToVector() + ",,,,,fff::"+ _ufpTransform.forward.ToVector()); _verCurSpeed = _verCurSpeed - g * FrameSyncManager.DeltaTime; //垂直上的初速度随时间的改变 _ufpTransform.Translate(_childObj.forward * MoveSpeed * FrameSyncManager.DeltaTime, Space.World); //水平上的运动 _ufpTransform.Translate(FPVector.up * _verCurSpeed * FrameSyncManager.DeltaTime, Space.World); //垂直上的运动 UpdateRotation(_ufpTransform.rotation); UpdatePosition(_ufpTransform.position); // transform.Translate(_childObj.forward.ToVector() * (MoveSpeed/** _frameEntityObj.SpeedRate*/).AsFloat() * Time.fixedDeltaTime, Space.World);//水平上的运动 // transform.Translate(Vector3.up * _verCurSpeed.AsFloat() * Time.fixedDeltaTime, Space.World);//垂直上的运动 FP angleForward = FPVector.Angle(_ufpTransform.up, FPVector.up); if (angleForward == 0) { return; } FPVector normal = FPVector.Cross(_ufpTransform.up, FPVector.up); // int DirctData = FPMath.Sign(FPVector.Dot(normal, _ufpTransform.up)); float DirctData = Mathf.Sign(Vector3.Dot(normal.ToVector(), _ufpTransform.up.ToVector())); //Debug.Log(" angleForward::" + angleForward.AsFloat() + ",DirctData::"+ DirctData + ",_ufpTransform.up::"+ _ufpTransform.up + " ,"+ _ufpTransform.up.ToVector() + ",FPVector.up::"+ FPVector.up.ToVector() // + ",normal::" + normal + "," + normal.ToVector() + ", FPVector.Dot(normal, _ufpTransform.up)::" + FPVector.Dot(normal, _ufpTransform.up).AsFloat()); //if (DirctData == 0) DirctData = 1; angleForward = angleForward * DirctData; // Debug.Log(" FPMath.Sign(FPVector.Dot(normal, _ufpTransform.up)::" + FPVector.Dot(new FPVector(0,0,1), new FPVector(1, 0, 0))); FPVector forwardVec3 = FPQuaternion.AngleAxis(angleForward, normal) * _ufpTransform.up; FPVector forwardForward = FPQuaternion.AngleAxis(angleForward, normal) * _ufpTransform.forward; FPQuaternion qur = FPQuaternion.LookRotation(forwardForward, forwardVec3); //Debug.Log("forwardForward:::" + forwardForward.ToVector() + ",,forwardVec3::" + forwardVec3.ToVector() // + ",angleForward::"+ angleForward.AsFloat() // + ",_ufpTransform.up::" + _ufpTransform.up.ToVector() + ", _ufpTransform.forward::" + _ufpTransform.forward.ToVector() // + ",normal::" + normal.ToVector()); UpdateRotation(FPQuaternion.Slerp(_ufpTransform.rotation, qur, 0.1f)); //_ufpTransform.SetRotation(); //transform.rotation = FPQuaternion.Slerp(_ufpTransform.rotation, qur, 0.1f); //将玩家处于空中的状态事件发射出去 TriggerEvent(DefineEventId.PlayerInAirEvent); } else { FP angle = FPVector.Angle(FPVector.up, _ufpTransform.ChangeVec3ToTSVec(_groundHit.normal)); if (angle > SlopeAngle) { if (!bMoveFlag) { _ufpTransform.Translate(-1 * (FPVector.up) * g * FrameSyncManager.DeltaTime, Space.World); UpdateRotation(_ufpTransform.rotation); UpdatePosition(_ufpTransform.position); } } else { // transform.position = new Vector3(transform/*.parent*/.position.x, _groundHit.point.y, transform/*.parent*/.position.z); UpdateRotation(_ufpTransform.rotation); UpdatePosition(new FPVector(_ufpTransform.position.x, (FP)(_groundHit.point.y), _ufpTransform.position.z)); } } }
public void Move() { if (bJumpFlag) { return; } FPVector groundNormal = FPVector.zero; RaycastHit hitInfo; if (!RayGroundInfo(out hitInfo)) { if (!bJumpFlag) { bMoveFlag = false; } return; //如果离地,直接返回 } else { groundNormal = new FPVector(hitInfo.normal.x, hitInfo.normal.y, hitInfo.normal.z); } if (!bMoveFlag) { bMoveFlag = true; } FPVector forward = _ufpTransform.forward; FPVector fpNormal = _ufpTransform.ChangeVec3ToTSVec(hitInfo.normal); RaycastHit barrierInfo; bool bExitBarrier = (RayBarrierInfo(_childObj.forward.ToVector(), out barrierInfo)); //表示前方检测到物体,暂时把检测到的物体都称之为障碍物 bool bSlope = false; //默认不是为斜坡标志 if (bExitBarrier) { hitInfo = barrierInfo; bSlope = (Vector3.Angle(Vector3.up, hitInfo.normal) > SlopeAngle) ? true : false; if (ForWardMode == E_ForWardMode.FM_ON_FORWARD) { forward = _ufpTransform.forward; } else { FP angle = 0; fpNormal = _ufpTransform.ChangeVec3ToTSVec(hitInfo.normal); if (groundNormal != FPVector.zero) { angle = FPVector.Angle(groundNormal, fpNormal); angle = -angle; } if (_childObj) { //Vector3 newCrossVec3 = Vector3.Cross(hitInfo.normal, transform.up); //forward = Quaternion.AngleAxis(angle, newCrossVec3) * (transform.forward); FPVector newCrossVec3 = FPVector.Cross(fpNormal, _ufpTransform.up); forward = FPQuaternion.AngleAxis(angle, newCrossVec3) * _ufpTransform.forward; } } } else { bSlope = ((FPVector.Angle(FPVector.up, fpNormal)) > SlopeAngle) ? true : false; } if (SurfaceMode == E_SurfaceMode.SM_ON_GROUND) //非跨面模式:供人型和乌贼模式下使用 { if (bExitBarrier && bSlope) { return; } } else if (SurfaceMode == E_SurfaceMode.SM_ON_SURFACE) //跨面模式:供乌贼下潜模式下使用 { if (bSlope) { MotionMode = E_MotionMode.MM_ON_LINE; bool flag = CanMoveByInk(ref hitInfo); //上墙后到边角的处理 ==>TODO flag = true; if (!flag) { FPVector position = _ufpTransform.ChangeVec3ToTSVec(hitInfo.point) + (_childObj.forward * MoveSpeed * 0.1f); FPVector currentPosition = _ufpTransform.position; //_ufpTransform.position = position; //transform.position = position.ToVector(); UpdatePosition(_ufpTransform.position); RayGroundInfo(out barrierInfo); flag = CanMoveByInk(ref barrierInfo); // transform.position = currentPosition.ToVector(); UpdatePosition(_ufpTransform.position); if (bExitBarrier || !flag) { return; } } } } if (hitInfo.transform != null && ForWardMode == E_ForWardMode.FM_ON_NORMAL) { FitSurfaceParent(forward, _ufpTransform.ChangeVec3ToTSVec(hitInfo.point), fpNormal); //调整贴面 } else if (hitInfo.transform != null && ForWardMode == E_ForWardMode.FM_ON_FORWARD) { if (transform.up != Vector3.up) { FP quaternionSpeed = 0.09f; FPQuaternion data = new FPQuaternion(0, _ufpTransform.rotation.y, 0, _ufpTransform.rotation.w); _ufpTransform.SetRotation(FPQuaternion.Slerp(_ufpTransform.rotation, data, quaternionSpeed)); } } if (MotionMode == E_MotionMode.MM_ON_ROUND) //画圆模式:按照圆的弧度来行走 { _destRoundData = RotationSpeed * MoveSpeed * FrameSyncManager.DeltaTime; _ufpTransform.RotateAround(_center, _ufpTransform.up, _destRoundData); //_destUfpTransform.position = _ufpTransform.position; //_destUfpTransform.rotation = _ufpTransform.rotation; //_destUfpTransform.RotateAround(_center, _ufpTransform.up, _destRoundData); Debug.Log("----------------->_characterMotion:::" + _destRoundData + ",_destRoundData::" + _destRoundData.AsFloat() + ",childObj.forward::" + _childObj.forward + ",childObj.forward.toVector3::" + _childObj.forward.ToVector()); } else if (MotionMode == E_MotionMode.MM_ON_LINE)//直走模式:按照其forward的方向行走 { _destVector = _childObj.forward * MoveSpeed * FrameSyncManager.DeltaTime; _ufpTransform.Translate(_destVector, Space.World); //_destUfpTransform.position = _ufpTransform.position; //_destUfpTransform.rotation = _ufpTransform.rotation; //_destUfpTransform.Translate(_destVector, Space.World); } // if (Physics.Raycast(RayPointObj.position + (_destUfpTransform.position - _ufpTransform.position).ToVector(), -transform.up, GroundRayLength)) if (Physics.Raycast(RayPointObj.position + (_ufpTransform.position.ToVector() - transform.position), -transform.up, GroundRayLength)) { _bHasSpeed = false; } else { _bHasSpeed = true; RenderEndUpdatePosition(); } _verCurSpeed = MoveSpeed / 2; }
public static void TRS(FPVector translation, FPQuaternion rotation, FPVector scale, out FPMatrix4x4 matrix) { matrix = FPMatrix4x4.Translate(translation) * FPMatrix4x4.Rotate(rotation) * FPMatrix4x4.Scale(scale); }
public static AnimatorData Extract(AnimationClip clip) { AnimatorData animationData = new AnimatorData(); animationData.clipName = clip.name; EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(clip); AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(clip); float usedTime = settings.stopTime - settings.startTime; animationData.frameRate = Mathf.RoundToInt(clip.frameRate); animationData.length = FP.FromFloat_UNSAFE(usedTime); animationData.frameCount = Mathf.RoundToInt(clip.frameRate * usedTime); animationData.frames = new AnimatorFrame[animationData.frameCount]; animationData.looped = clip.isLooping && settings.loopTime; animationData.mirror = settings.mirror; //Read the curves of animation int frameCount = animationData.frameCount; int curveBindingsLength = curveBindings.Length; if (curveBindingsLength == 0) { return(animationData); } AnimationCurve curveTx = null, curveTy = null, curveTz = null, curveRx = null, curveRy = null, curveRz = null, curveRw = null; for (int c = 0; c < curveBindingsLength; c++) { string propertyName = curveBindings[c].propertyName; if (propertyName == "m_LocalPosition.x" || propertyName == "RootT.x") { curveTx = AnimationUtility.GetEditorCurve(clip, curveBindings[c]); } if (propertyName == "m_LocalPosition.y" || propertyName == "RootT.y") { curveTy = AnimationUtility.GetEditorCurve(clip, curveBindings[c]); } if (propertyName == "m_LocalPosition.z" || propertyName == "RootT.z") { curveTz = AnimationUtility.GetEditorCurve(clip, curveBindings[c]); } if (propertyName == "m_LocalRotation.x" || propertyName == "RootQ.x") { curveRx = AnimationUtility.GetEditorCurve(clip, curveBindings[c]); } if (propertyName == "m_LocalRotation.y" || propertyName == "RootQ.y") { curveRy = AnimationUtility.GetEditorCurve(clip, curveBindings[c]); } if (propertyName == "m_LocalRotation.z" || propertyName == "RootQ.z") { curveRz = AnimationUtility.GetEditorCurve(clip, curveBindings[c]); } if (propertyName == "m_LocalRotation.w" || propertyName == "RootQ.w") { curveRw = AnimationUtility.GetEditorCurve(clip, curveBindings[c]); } } // if (curveBindingsLength >= 7) // { // //Position Curves // curveTx = AnimationUtility.GetEditorCurve(clip, curveBindings[0]); // curveTy = AnimationUtility.GetEditorCurve(clip, curveBindings[1]); // curveTz = AnimationUtility.GetEditorCurve(clip, curveBindings[2]); // // //Rotation Curves // curveRx = AnimationUtility.GetEditorCurve(clip, curveBindings[3]); // curveRy = AnimationUtility.GetEditorCurve(clip, curveBindings[4]); // curveRz = AnimationUtility.GetEditorCurve(clip, curveBindings[5]); // curveRw = AnimationUtility.GetEditorCurve(clip, curveBindings[6]); // } bool hasPosition = curveTx != null && curveTy != null && curveTz != null; bool hasRotation = curveRx != null && curveRy != null && curveRz != null && curveRw != null; if (!hasPosition) { Debug.LogWarning("No movement data was found in the animation: " + clip.name); } if (!hasRotation) { Debug.LogWarning("No rotation data was found in the animation: " + clip.name); } //The initial pose might not be the first frame and might not face foward //calculate the initial direction and create an offset Quaternion to apply to transforms; Quaternion startRotUq = Quaternion.identity; FPQuaternion startRot = FPQuaternion.Identity; if (hasRotation) { float srotxu = curveRx.Evaluate(settings.startTime); float srotyu = curveRy.Evaluate(settings.startTime); float srotzu = curveRz.Evaluate(settings.startTime); float srotwu = curveRw.Evaluate(settings.startTime); FP srotx = FP.FromFloat_UNSAFE(srotxu); FP sroty = FP.FromFloat_UNSAFE(srotyu); FP srotz = FP.FromFloat_UNSAFE(srotzu); FP srotw = FP.FromFloat_UNSAFE(srotwu); startRotUq = new Quaternion(srotxu, srotyu, srotzu, srotwu); startRot = new FPQuaternion(srotx, sroty, srotz, srotw); } Quaternion offsetRotUq = Quaternion.Inverse(startRotUq); FPQuaternion offsetRot = FPQuaternion.Inverse(startRot); for (int i = 0; i < frameCount; i++) { var frameData = new AnimatorFrame(); frameData.id = i; float percent = i / (frameCount - 1f); float frameTime = usedTime * percent; frameData.time = FP.FromFloat_UNSAFE(frameTime); float clipTIme = settings.startTime + percent * (settings.stopTime - settings.startTime); if (hasPosition) { FP posx = FP.FromFloat_UNSAFE(i > 0 ? curveTx.Evaluate(clipTIme) - curveTx.Evaluate(settings.startTime) : 0); FP posy = FP.FromFloat_UNSAFE(i > 0 ? curveTy.Evaluate(clipTIme) - curveTy.Evaluate(settings.startTime) : 0); FP posz = FP.FromFloat_UNSAFE(i > 0 ? curveTz.Evaluate(clipTIme) - curveTz.Evaluate(settings.startTime) : 0); FPVector3 newPosition = offsetRot * new FPVector3(posx, posy, posz); if (settings.mirror) { newPosition.X = -newPosition.X; } frameData.position = newPosition; } if (hasRotation) { float curveRxEval = curveRx.Evaluate(clipTIme); float curveRyEval = curveRy.Evaluate(clipTIme); float curveRzEval = curveRz.Evaluate(clipTIme); float curveRwEval = curveRw.Evaluate(clipTIme); Quaternion curveRotation = offsetRotUq * new Quaternion(curveRxEval, curveRyEval, curveRzEval, curveRwEval); if (settings.mirror)//mirror the Y axis rotation { Quaternion mirrorRotation = new Quaternion(curveRotation.x, -curveRotation.y, -curveRotation.z, curveRotation.w); if (Quaternion.Dot(curveRotation, mirrorRotation) < 0) { mirrorRotation = new Quaternion(-mirrorRotation.x, -mirrorRotation.y, -mirrorRotation.z, -mirrorRotation.w); } curveRotation = mirrorRotation; } FP rotx = FP.FromFloat_UNSAFE(curveRotation.x); FP roty = FP.FromFloat_UNSAFE(curveRotation.y); FP rotz = FP.FromFloat_UNSAFE(curveRotation.z); FP rotw = FP.FromFloat_UNSAFE(curveRotation.w); FPQuaternion newRotation = new FPQuaternion(rotx, roty, rotz, rotw); frameData.rotation = newRotation * offsetRot; float rotY = curveRotation.eulerAngles.y * Mathf.Deg2Rad; while (rotY < -Mathf.PI) { rotY += Mathf.PI * 2; } while (rotY > Mathf.PI) { rotY += -Mathf.PI * 2; } frameData.rotationY = FP.FromFloat_UNSAFE(rotY); } animationData.frames[i] = frameData; } return(animationData); }
private void UpdateRotation(FPQuaternion rotation) { _ufpTransform.SetRotation(rotation); _childObj.UpdateFpRotation(new FPQuaternion(_childObj.transform.rotation.x, _childObj.transform.rotation.y, _childObj.transform.rotation.z, _childObj.transform.rotation.w)); }
private void AnimationClipGui(AnimatorClip clip) { EditorGUILayout.BeginVertical("box", GUILayout.Width(EditorGUIUtility.currentViewWidth - 20)); EditorGUILayout.LabelField("Animator Clip"); EditorGUILayout.LabelField(string.Format("Name: {0}", clip.clipName)); EditorGUILayout.LabelField(string.Format("Length: {0}", clip.data.length.AsFloat)); EditorGUILayout.LabelField(string.Format("Frame Rate: {0}", clip.data.frameRate)); EditorGUILayout.LabelField(string.Format("Frame Count: {0}", clip.data.frameCount)); EditorGUILayout.LabelField(string.Format("Looped: {0}", clip.data.looped)); EditorGUILayout.LabelField(string.Format("Mirrored: {0}", clip.data.mirror)); int frameCount = clip.data.frameCount; Vector3[] positions = new Vector3[frameCount]; Quaternion[] rotationsQ = new Quaternion[frameCount]; Vector3[] rotations = new Vector3[frameCount]; float[] times = new float[frameCount]; for (int f = 0; f < frameCount; f++) { AnimatorFrame frame = clip.data.frames[f]; float frameTime = frame.time.AsFloat; FPVector3 position = frame.position; FPQuaternion rotation = frame.rotation; Vector3 pV3 = new Vector3(position.X.AsFloat, position.Y.AsFloat, position.Z.AsFloat); Quaternion rQ = new Quaternion(rotation.X.AsFloat, rotation.Y.AsFloat, rotation.Z.AsFloat, rotation.W.AsFloat); Vector3 rV3 = rQ.eulerAngles; positions[f] = pV3; rotationsQ[f] = rQ; rotations[f] = rV3; times[f] = frameTime; } EditorGUILayout.BeginVertical("box"); EditorGUILayout.LabelField(string.Format("Delta Movement: {0}", (positions[frameCount - 1] - positions[0]).ToString("F3"))); Quaternion deltaQ = Quaternion.FromToRotation(rotationsQ[0] * Vector3.forward, rotationsQ[frameCount - 1] * Vector3.forward); Vector3 deltaQV = deltaQ.eulerAngles; if (deltaQV.x > 180) { deltaQV.x += -360; } if (deltaQV.y > 180) { deltaQV.y += -360; } if (deltaQV.z > 180) { deltaQV.z += -360; } EditorGUILayout.LabelField(string.Format("Delta Rotation: {0}", deltaQV.ToString("F3"))); EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical("box"); if (showMovementData = EditorGUILayout.Foldout(showMovementData, "Movement Data")) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginVertical(); EditorGUILayout.LabelField("Times", GUILayout.Width(75)); for (int f = 0; f < frameCount; f++) { EditorGUILayout.LabelField(times[f].ToString("F3"), GUILayout.Width(75)); } EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); EditorGUILayout.LabelField("Positions", GUILayout.Width(160)); for (int f = 0; f < frameCount; f++) { EditorGUILayout.LabelField(positions[f].ToString("F2"), GUILayout.Width(160)); } EditorGUILayout.EndVertical(); EditorGUILayout.BeginVertical(); EditorGUILayout.LabelField("Rotations", GUILayout.Width(160)); for (int f = 0; f < frameCount; f++) { EditorGUILayout.LabelField(rotations[f].ToString("F2"), GUILayout.Width(160)); } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); EditorGUILayout.EndVertical(); }
public void Update() { if (Target == null) { return; } // ChangeDirectionByDragging(); //if (_dragging && _directorToLeft && !_bTouchMouse) //左遥感 //{ // _rockerControl = ComMoveController.RockerControl.LeftControl; // _ufpTransform.RotateAround(_playerTransformObj.position, FPVector.up, FrameSyncManager.DeltaTime * RockerSpeed); // _ufpTransform.UpdateAllData(); // Debug.Log("_ufpTransform:::" + _ufpTransform.forward.ToVector()); // //transform.RotateAround(_childObj.position, Vector3.up, Time.deltaTime * RockerSpeed); // return; //} //else if (_dragging && _directorToRight && !_bTouchMouse) //右遥感 //{ // _rockerControl = ComMoveController.RockerControl.RightControl; // _ufpTransform.RotateAround(_playerTransformObj.position, FPVector.up, FrameSyncManager.DeltaTime * -RockerSpeed); // _ufpTransform.UpdateAllData(); // // transform.RotateAround(_childObj.position, Vector3.up, Time.deltaTime * -RockerSpeed); // return; //} //Debug.Log("_currentAngle:::" + _currentAngle + ",_childObj.eulerAngles.y::" + _childObj.eulerAngles.y // + ",transform.rotation::"+ transform.rotation); RaycastHit GroundHitInfo; RaycastHit BarrieHitrInfo; bool bGroundInfoFlag = _motionObj.RayGroundInfo(out GroundHitInfo); bool bBarrierInfoFlag = _motionObj.RayBarrierInfo(_childTransformObj.forward.ToVector(), out BarrieHitrInfo); FPVector fpGroundInfoNormal = FPVector.zero; if (bGroundInfoFlag) { fpGroundInfoNormal = GroundHitInfo.normal.ToFPVector(); } if (!_dragging && !_bTouchMouse && _bBeforeDragging) { _rockerControl = ComMoveController.RockerControl.None; return; } else if (!_dragging) { if (_bBeforeDragging) //在这里设置值,为了保证childObj的forward朝向跟摄像机的一致,防止先后差值 { _bBeforeDragging = false; return; } if (!bGroundInfoFlag) //在空中 { _rockerControl = ComMoveController.RockerControl.AirControl; if (_motionObj.bJumpFlag && false) //这是处理不跟随着对象跳跃的逻辑部分 { Distance = FPMath.Clamp(Distance - (Input.GetAxis("Mouse ScrollWheel") * MouseScrollWheelSensitivity), DistanceMin, DistanceMax); FPVector DataVec3 = new FPVector(_playerTransformObj.position.x, transform.position.y - Height, _playerTransformObj.position.z); _ufpTransform.position = (_ufpTransform.rotation * new FPVector(.0f, Height, -Distance)) + DataVec3; _ufpTransform.UpdateAllData(); return; } } else if (!bBarrierInfoFlag || !_motionObj.JudgetGroundSlope(BarrieHitrInfo.normal)) //有地面接触但前方没有障碍物 { if (!_motionObj.JudgetGroundSlope(GroundHitInfo.normal)) { _rockerControl = ComMoveController.RockerControl.OtherControl; _climbOtherWall = false; } else { if (_climbOtherWall && _beforeWallNormalVec3 != fpGroundInfoNormal) //表示从一面墙跨到另外一面墙 { _beforeGroundNormalVec3 = _beforeWallNormalVec3; _beforeWallNormalVec3 = fpGroundInfoNormal; } _rockerControl = ComMoveController.RockerControl.ClimbControl; } } else //有地面接触且前方有障碍物 { _rockerControl = ComMoveController.RockerControl.None; _beforeControl = ComMoveController.RockerControl.OtherControl; if (!_motionObj.JudgetGroundSlope(GroundHitInfo.normal)) //从地面跨到墙上的情况 { _beforeGroundNormalVec3 = fpGroundInfoNormal; } else //从一面墙跨到另外一面墙的情况 { _climbOtherWall = true; _beforeWallNormalVec3 = fpGroundInfoNormal; //设置这个变量的原因是:有可能检测到障碍物,但是玩家并没有跨越过去 } } } if (_rockerControl == RockerControl.AirControl) { Distance = FPMath.Clamp(Distance - (Input.GetAxis("Mouse ScrollWheel") * MouseScrollWheelSensitivity), DistanceMin, DistanceMax); _ufpTransform.position = (_ufpTransform.rotation * new FPVector(.0f, Height, -Distance)) + _playerTransformObj.position; _ufpTransform.UpdateAllData(); } else if (_rockerControl == RockerControl.OtherControl) { var quaternion = FPQuaternion.AngleAxis((_currentAngle) + _childTransformObj.transform.eulerAngles.y, FPVector.up); Distance = FPMath.Clamp(Distance - (Input.GetAxis("Mouse ScrollWheel") * MouseScrollWheelSensitivity), DistanceMin, DistanceMax); _ufpTransform.SetRotation(quaternion); // transform.rotation = quaternion; FPVector data = (_ufpTransform.rotation * new FPVector(.0f, Height, -Distance)); _ufpTransform.position = (_ufpTransform.rotation * new FPVector(.0f, Height, -Distance)) + _playerTransformObj.position; _ufpTransform.UpdatePosition(); //Debug.Log("data::"+ data.ToVector()+ ", _ufpTransform.position::::" + _ufpTransform.position.ToVector() // + ",transform::" + transform.position + "::_playerTransformObj.position:" + _playerTransformObj.position.ToVector() // + ",,name::" + _playerTransformObj.gameObject.name); _rotation = _ufpTransform.rotation; _ufpTransform.UpdateForward(); } else if (_rockerControl == RockerControl.ClimbControl) { Distance = FPMath.Clamp(Distance - (Input.GetAxis("Mouse ScrollWheel") * MouseScrollWheelSensitivity), DistanceMin, DistanceMax); var quaternion = FPQuaternion.AngleAxis((0) + transform.eulerAngles.y, FPVector.up); _ufpTransform.position = (_ufpTransform.rotation * new FPVector(.0f, Height, -Distance)) + _playerTransformObj.position; _ufpTransform.UpdateAllData(); FPVector climbForward = _ufpTransform.forward; if (_beforeControl == ComMoveController.RockerControl.OtherControl && _beforeGroundNormalVec3 != FPVector.zero) { FP tempAngle = FPVector.Angle(_beforeGroundNormalVec3, fpGroundInfoNormal); FPVector normal = FPVector.Cross(_beforeGroundNormalVec3, fpGroundInfoNormal); //叉乘求出法线向量 // num *= Mathf.Sign(Vector3.Dot(normal, info.transform.up)); //求法线向量与物体上方向向量点乘,结果为1或-1,修正旋转方向 climbForward = FPQuaternion.AngleAxis((90 - tempAngle), normal) * fpGroundInfoNormal; climbForward = -1 * climbForward; _finishWallNormalVec3 = climbForward; _beforeControl = ComMoveController.RockerControl.ClimbControl; } FP forwardAngle = FPVector.Angle(_finishWallNormalVec3, _ufpTransform.forward); if (forwardAngle != 0 && false) //处理摄像机角度偏转 { //1)调整摄像机的旋转角度 float direcFlag = -1; FPVector normalVec3 = FPVector.Cross(_finishWallNormalVec3, _ufpTransform.forward); //叉乘求出法线向量 direcFlag *= FPMath.Sign(Vector3.Dot(normalVec3.ToVector(), _ufpTransform.up.ToVector())); //求法线向量与物体上方向向量点乘,结果为1或-1,修正旋转方向 forwardAngle *= direcFlag; FPVector beforeForward = _ufpTransform.forward; FPVector forward = FPQuaternion.AngleAxis(forwardAngle, _ufpTransform.up) * _ufpTransform.forward; // Debug.Log("_ufpTransform.forward::" + _ufpTransform.forward.ToVector() + ",forward::" + forward.ToVector() // + "forwardAngle:::" + forwardAngle.AsFloat() + ",forward1111::" + forward); float quaternionSpeed = 0.003f; if (!_bTouchMouse) { quaternionSpeed = 0.03f; } if (beforeForward != forward) { Debug.Log("LookRotation(forward):::" + FPQuaternion.LookRotation(forward) + ",_rotation::" + _rotation + ",unity::" + Quaternion.LookRotation(forward.ToVector())); _rotation = FPQuaternion.Slerp(_rotation, FPQuaternion.LookRotation(forward), quaternionSpeed); _ufpTransform.SetRotation(_rotation); } // Debug.Log(",forward::"+ forward.ToVector() + ",_ufpTransform.forward::" + _ufpTransform.forward.ToVector()); //2)调整人物的旋转角度 if (!_climbOtherWall) // 这是从地面爬到墙得处理,如果是从一面墙爬到另外一面墙,镜头不做转换 { Debug.Log("beforeForward:::" + beforeForward.ToVector() + ",_ufpTransform.forward::" + _ufpTransform.forward.ToVector()); _offsetAngle = FPVector.Angle(beforeForward, _ufpTransform.forward) * direcFlag; _avatarObj.ChangeAvaterForward(_offsetAngle); } } } Debug.DrawLine(_ufpTransform.position.ToVector(), _playerTransformObj.transform.position, Color.red); if (_rockerControl == RockerControl.OtherControl || _rockerControl == RockerControl.ClimbControl) { //看是否有障碍物 FPVector directionTarget = (_ufpTransform.position - _ufpTransform.ChangeVec3ToTSVec(_rayPointObj.position)).normalized; FP distance = FPVector.Distance(_ufpTransform.position, _ufpTransform.ChangeVec3ToTSVec(_rayPointObj.position)); if (distance > Distance) { _ufpTransform.Translate(directionTarget * (distance - Distance)); _ufpTransform.UpdateRotationAndPosition(); } // Debug.DrawRay(_rayPointObj.position, directionTarget * Distance, Color.black); int layerMask = LayerMask.GetMask(Layers.Render); RaycastHit info; if (Physics.Raycast(_rayPointObj.position, directionTarget.ToVector(), out info, Distance.AsFloat(), layerMask)) //如果 { // Debug.Log("info.name::" + info.transform.name); if (info.transform.name != transform.name /*&& info.transform.tag != Tags.Ground*/) { _ufpTransform.SetPosition(_ufpTransform.ChangeVec3ToTSVec(info.point)); //transform.position = info.point; } if (_rockerControl == RockerControl.OtherControl) { _beforeControl = RockerControl.OtherControl; } } } }