Edy's Vehicle Physics汽车物理模拟源码分析

1,镜头跟随源码分析

         LookAt模式关键源码;

            

public override void Update (Transform self, Transform target, Vector3 targetOffset)
		{
		// Position

		if (enableMovement)
			{
			float stepSize = movementSpeed * Time.deltaTime;

			m_position += GetInputForAxis(forwardAxis) * stepSize * new Vector3(self.forward.x, 0.0f, self.forward.z).normalized;
			m_position += GetInputForAxis(sidewaysAxis) * stepSize * self.right;
			m_position += GetInputForAxis(verticalAxis) * stepSize * self.up;
			}

		self.position = Vector3.Lerp(self.position, m_position, movementDamping * Time.deltaTime);

		// Rotation

		if (target != null)
			{
			Quaternion lookAtRotation = Quaternion.LookRotation(target.position + targetOffset - self.position);
			self.rotation = Quaternion.Slerp(self.rotation, lookAtRotation, damping * Time.deltaTime);
			}

		// Zoom

		if (m_camera != null)
			{
			m_fov -= GetInputForAxis(fovAxis) * fovSpeed;
			m_fov = Mathf.Clamp(m_fov, minFov, maxFov);
			m_camera.fieldOfView = Mathf.Lerp(m_camera.fieldOfView, m_fov, fovDamping * Time.deltaTime);
			}
		}

         绿色标记代码表示先获取一个代表摄像机位置指向汽车位置的时的旋转,再将其插值计算后赋值给摄像机自身的rotation,

damping参数使摄像机存在缓冲效果,而并不是实时指向汽车。

         Quaternion.LookRotation方法有两个Vector3类型的参数,第一个参数表示看向的方向,第二个参数起约束作用

默认为Vector3.up.

        蓝色标记代码表示通过鼠标滚轮对摄像机的视野范围进行控制,同时也进行了插值计算。

        

        SmoothFollow模式(平滑跟随);

        以下为自定义Update方法内容

public override void Update (Transform self, Transform target, Vector3 targetOffset)
		{
		if (target == null) return;
		//updatedVelocity为当前帧target的移动速度,m_smoothLastPos保存上一帧的target的移动速度;
		Vector3 updatedVelocity = (target.position + targetOffset - m_smoothLastPos) / Time.deltaTime;
		m_smoothLastPos = target.position + targetOffset;

		updatedVelocity.y = 0.0f;//将y轴上的速度设为0,使得摄像机只会在水平面改变方向;

		if (updatedVelocity.magnitude > 1.0f)
			{
			m_smoothVelocity = Vector3.Lerp(m_smoothVelocity, updatedVelocity, velocityDamping * Time.deltaTime);
			m_smoothTargetAngle = Mathf.Atan2(m_smoothVelocity.x, m_smoothVelocity.z) * Mathf.Rad2Deg;
			}

		if (!followVelocity)
			m_smoothTargetAngle = target.eulerAngles.y;

		float wantedHeight = target.position.y + targetOffset.y + height;

		m_selfRotationAngle = Mathf.LerpAngle(m_selfRotationAngle, m_smoothTargetAngle, rotationDamping * Time.deltaTime);
		m_selfHeight = Mathf.Lerp(m_selfHeight, wantedHeight, heightDamping * Time.deltaTime);
		Quaternion currentRotation = Quaternion.Euler (0, m_selfRotationAngle, 0);//创建一个插值计算后的旋转;

		Vector3 selfPos = target.position + targetOffset;
		selfPos -= currentRotation * Vector3.forward * distance;
		selfPos.y = m_selfHeight;//通过向量运算得到本帧结束时摄像机的位置;

		Vector3 lookAtTarget = target.position + targetOffset + Vector3.up * height * viewHeightRatio;//设置摄像机lookat对象的位置

		if (m_vehicle != null && controller.cameraCollisions)
			{
			if (m_camera != null)
				{//检测self位置和lookAtTarget位置之间是否存在其他物体
				Vector3 origin = lookAtTarget;
				Vector3 path = selfPos - lookAtTarget;
				Vector3 direction = path.normalized;
				float rayDistance = path.magnitude - m_camera.nearClipPlane;
				float radius = m_camera.nearClipPlane * Mathf.Tan(m_camera.fieldOfView * Mathf.Deg2Rad * 0.5f) + 0.1f;

				selfPos = origin + direction * m_vehicle.SphereRaycastOthers(origin, direction, radius, rayDistance, controller.collisionMask);
				}
			else
				{
				selfPos = m_vehicle.RaycastOthers(lookAtTarget, selfPos, controller.collisionMask);
				}
			}

		self.position = selfPos;
		self.LookAt(lookAtTarget);
		}
	}
             原理:



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值