600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 3D游戏小总结(第一人称 第三人称实现)

3D游戏小总结(第一人称 第三人称实现)

时间:2019-05-01 20:24:16

相关推荐

3D游戏小总结(第一人称 第三人称实现)

一:简易第一人称视角控制

private Transform cameraTransform;//相机[SerializeField] private Transform characterTransform;//人物private Vector3 cameraRotation;public float MouseSensitivity;//5public Vector2 MaxminAngle;//(-65,65)private void Start(){cameraTransform = transform;}void Update(){var tmp_MouseX = Input.GetAxis("Mouse X");var tmp_MouseY = Input.GetAxis("Mouse Y");cameraRotation.x -= tmp_MouseY * MouseSensitivity;cameraRotation.y += tmp_MouseX * MouseSensitivity;cameraRotation.x = Mathf.Clamp(cameraRotation.x, MaxminAngle.x, MaxminAngle.y);//限制人物的俯仰角度characterTransform.rotation = Quaternion.Euler(0, cameraRotation.y, 0);//人物旋转跟随鼠标cameraTransform.rotation = Quaternion.Euler(cameraRotation.x, cameraRotation.y, 0); //控制相机的旋转和人物的旋转保持一致

二:第一人称移动控制

(1):常规控制移动方法:

using System.Collections;using System.Collections.Generic;using UnityEngine;public class FPSMoveMovement : MonoBehaviour{public float Speed;public float JumpHeight;public float gravity;private Transform characterTransform;private Rigidbody characterRigidbody;private bool isGrounded;// Start is called before the first frame updatevoid Start(){characterTransform = transform;characterRigidbody = GetComponent<Rigidbody>();}// Update is called once per framevoid Update(){}private void FixedUpdate(){if (isGrounded){var tmp_Horizontal = Input.GetAxis("Horizontal");var tmp_Vertical = Input.GetAxis("Vertical");var tmp_CurrentDirection = new Vector3(tmp_Horizontal, 0, tmp_Vertical);tmp_CurrentDirection = characterTransform.TransformDirection(tmp_CurrentDirection);//将角色的局部坐标转化为世界坐标tmp_CurrentDirection *= Speed;var tmp_CurrentVelocity = characterRigidbody.velocity;var tmp_VelocityChange = tmp_CurrentDirection - tmp_CurrentVelocity;tmp_VelocityChange.y = 0;//控制角色的移动characterRigidbody.AddForce(tmp_VelocityChange, ForceMode.VelocityChange);//控制角色的跳跃if (Input.GetButtonDown("Jump")){characterRigidbody.velocity=new Vector3(tmp_CurrentVelocity.x,CalculateJumpHeightSpeed(),tmp_CurrentVelocity.z);}}characterRigidbody.AddForce(new Vector3(0, -gravity*characterRigidbody.mass, 0)); //控制角色的下落速度}//控制角色的跳跃高度private float CalculateJumpHeightSpeed(){return Mathf.Sqrt(2 * gravity * JumpHeight);}private void OnCollisionStay(Collision collision){isGrounded = true;}private void OnCollisionExit(Collision collision){isGrounded = false;}}

(2):通过CharaCterController控制人物的移动方法

using System;using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.Serialization;public class FPCharacterControllerMovement : MonoBehaviour{private CharacterController characterController;private Animator characterAnimator;private Vector3 movementDirection;private Transform characterTransform;private float velocity;private bool isCrouched;private float originHeight;public float SprintingSpeed;public float WalkSpeed;public float SprintingSpeedWhenCrouched;public float WalkSpeedWhenCrouched;public float Gravity = 9.8f;public float JumpHeight;public float CrouchHeight = 1f;private void Start(){characterController = GetComponent<CharacterController>();characterAnimator = GetComponentInChildren<Animator>();characterTransform = transform;originHeight = characterController.height;}private void Update(){float tmp_CurrentSpeed = WalkSpeed;if (characterController.isGrounded)//CharacterController是否在最后一次移动接触地面{var tmp_Horizontal = Input.GetAxis("Horizontal");var tmp_Vertical = Input.GetAxis("Vertical");movementDirection =characterTransform.TransformDirection(new Vector3(tmp_Horizontal, 0, tmp_Vertical));//将局部坐标转换为世界坐标//控制人物的跳跃if (Input.GetButtonDown("Jump")){movementDirection.y = JumpHeight;}//控制人物的下蹲if (Input.GetKeyDown(KeyCode.C)){var tmp_CurrentHeight = isCrouched ? originHeight : CrouchHeight;StartCoroutine(DoCrouch(tmp_CurrentHeight));isCrouched = !isCrouched;}//控制人物下蹲、站立的移动速度if (isCrouched){tmp_CurrentSpeed = Input.GetKey(KeyCode.LeftShift) ? SprintingSpeedWhenCrouched : WalkSpeedWhenCrouched;}else{tmp_CurrentSpeed = Input.GetKey(KeyCode.LeftShift) ? SprintingSpeed : WalkSpeed;}var tmp_Velocity = characterController.velocity;tmp_Velocity.y = 0;velocity = tmp_Velocity.magnitude;//返回角色的移动速度characterAnimator.SetFloat("Velocity", velocity, 0.25f, Time.deltaTime);//控制人物动画的播放}movementDirection.y -= Gravity * Time.deltaTime;//角色受重力下降的效果characterController.Move(tmp_CurrentSpeed * Time.deltaTime * movementDirection);//控制角色的移动}/// <summary>/// 下蹲方法/// </summary>/// <param name="_target"></param>/// <returns></returns>private IEnumerator DoCrouch(float _target){float tmp_CurrentHeight = 0;while (Mathf.Abs(characterController.height - _target) > 0.1f){yield return null;characterController.height =Mathf.SmoothDamp(characterController.height, _target,ref tmp_CurrentHeight, Time.deltaTime * 5);}}}

人物行走状态的动画BlendTree

三:第三人称角色移动控制

using System.Collections;using System.Collections.Generic;using UnityEngine;public class M_PlayerController : MonoBehaviour{private bool m_IsGrounded;//是否在地面上private float m_GroundCheckDistance = 1.33f;//射线检测地面的距离 从射线发射位置到地面的距离再加0.1f(具体数值自行测试)public float MoveSpeed = 10.0f; //移动速度public float RotateSpeed = 10.0f;//旋转速度private Rigidbody rig;//角色的刚体组件private float h, v;Vector3 c;//指向玩家单位向量public Camera Camera_self;//相机void Start(){rig = transform.GetComponent<Rigidbody>();c = (transform.position - Camera_self.transform.position).normalized;}private void Update(){CheckGroundStatus();Move();if (Input.GetKeyDown(KeyCode.Space) && m_IsGrounded)//跳跃{rig.velocity = new Vector3(0, 5, 0);}}/// <summary>/// 人物移动/// </summary>public void Move(){h = Input.GetAxis("Horizontal");v = Input.GetAxis("Vertical");float inputMotionValue = Mathf.Max(Mathf.Abs(h), Mathf.Abs(v));c = (transform.position - Camera_self.transform.position).normalized;//将角色的方向和相机的方向关联起来 从而达到旋转相机 人物也跟随旋转string s = transform.localEulerAngles.ToString();//欧拉角string[] sarr = s.Split(',');sarr = sarr[0].Split('(');float anglex = float.Parse(sarr[1]);//rotation的x值c.y = Mathf.Tan((360 - anglex) * Mathf.Deg2Rad);//正切(弧度)Vector3 cc = Quaternion.AngleAxis(90, Vector3.up) * c;//c绕y轴旋转90度Vector3 forward = c * v + cc * h;if (inputMotionValue > 0){Quaternion lookRot = Quaternion.LookRotation(forward);transform.rotation = Quaternion.Slerp(transform.rotation, lookRot, RotateSpeed * inputMotionValue * Time.deltaTime);transform.Translate(Vector3.forward * inputMotionValue * MoveSpeed * Time.deltaTime);}}/// <summary>/// 检测地面/// </summary>void CheckGroundStatus(){RaycastHit hitInfo;Debug.DrawLine(transform.position + (Vector3.up * 0.1f), transform.position + (Vector3.up * 0.1f) + (Vector3.down * m_GroundCheckDistance));if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance)){m_IsGrounded = true; }else{m_IsGrounded = false;}}}

四:第三人称相机控制

using System.Collections;using System.Collections.Generic;using UnityEngine;public class M_CameraController : MonoBehaviour{public enum RotateType{UableRotate,HorizontalOnly,VerticalOnly,Both}public enum UpdateType{LateUpdate,FixedUpdate,Update}public Transform target;public Vector3 headOffset = new Vector3(0, 1.7f, 0);public LayerMask ignoreLayer;public UpdateType updateType;public bool smooth;[Range(0.1f, 1f)] public float smoothLevel = 0.5f;public RotateType rotateType;public float rotateSpeed = 10.0f;//旋转速度public float zoomSpeed = 5f;//缩放速度public float minDistance = 3.0f;public float maxDistance = 15.0f;public float maxLookUpAngle = 70.0f;public float maxLookDownAngle = 30.0f;float OriginDistance;float currentDistance;Vector3 direction;Vector3 disOffset;Vector3 visibleEuler;// Use this for initializationvoid Start(){ResetView();}// Update is called once per framevoid Update(){if (updateType == UpdateType.Update){visibleEuler = ConvertEulerAngle(transform.rotation.eulerAngles);float h = Input.GetAxis("Mouse X");float v = Input.GetAxis("Mouse Y");float zoom = Input.GetAxis("Mouse ScrollWheel");Translate(zoom);Rotate(h, v);}}private void LateUpdate(){if (updateType == UpdateType.LateUpdate){visibleEuler = ConvertEulerAngle(transform.rotation.eulerAngles);float h = Input.GetAxis("Mouse X");float v = Input.GetAxis("Mouse Y");float zoom = Input.GetAxis("Mouse ScrollWheel");Translate(zoom);Rotate(h, v);}}private void FixedUpdate(){if (updateType == UpdateType.FixedUpdate){visibleEuler = ConvertEulerAngle(transform.rotation.eulerAngles);float h = Input.GetAxis("Mouse X");float v = Input.GetAxis("Mouse Y");float zoom = Input.GetAxis("Mouse ScrollWheel");Translate(zoom);Rotate(h, v);}}/// <summary>/// 控制相机的移动/// </summary>/// <param name="zoom"></param>void Translate(float zoom){OriginDistance -= zoom * zoomSpeed;OriginDistance = Mathf.Clamp(OriginDistance, minDistance, maxDistance);//限制缩放的范围RaycastHit hit;if (Physics.Raycast(target.position + headOffset, transform.position - target.position - headOffset, out hit, OriginDistance,~ignoreLayer, QueryTriggerInteraction.Ignore))//检测层依据需求更改{currentDistance = hit.distance;}else{currentDistance = OriginDistance;}disOffset = direction.normalized * currentDistance;if (smooth && rotateType == RotateType.Both)//平滑移动,但累计差会导致相机逐渐回到某个特定视角,且伴随有轻微抖动transform.position = Vector3.Lerp(transform.position, target.position + headOffset + disOffset, smoothLevel);elsetransform.position = target.position + headOffset + disOffset;//旋转时伴随轻微卡顿transform.LookAt(target.position + headOffset);disOffset = Vector3.zero;}/// <summary>/// 控制相机绕角色旋转/// </summary>/// <param name="h">鼠标左右方向移动数值</param>/// <param name="v">鼠标前后方向移动数值</param>void Rotate(float h, float v){if (rotateType != RotateType.UableRotate){float finallyRotateV = v * rotateSpeed;if (finallyRotateV + visibleEuler.x >= maxLookUpAngle){finallyRotateV = visibleEuler.x + finallyRotateV - maxLookUpAngle;}else if (finallyRotateV + visibleEuler.x <= -maxLookDownAngle){finallyRotateV = visibleEuler.x + finallyRotateV + maxLookDownAngle;}if (rotateType == RotateType.Both){//左右旋转transform.RotateAround(target.position + headOffset, transform.up, h * rotateSpeed);//上下旋转transform.RotateAround(target.position + headOffset, transform.right, -finallyRotateV);}else if (rotateType == RotateType.HorizontalOnly){transform.RotateAround(target.position + headOffset, Vector3.up, h * rotateSpeed);}else if (rotateType == RotateType.VerticalOnly){transform.RotateAround(target.position + headOffset, transform.right, -finallyRotateV);}transform.LookAt(target.position + headOffset);//相机一直朝着主角望去direction = (transform.position - target.position - headOffset).normalized;}}public float ConvertAngle(float value){float angle = value - 180;if (angle > 0)return angle - 180;return angle + 180;}public Vector3 ConvertEulerAngle(Vector3 euler){return new Vector3(ConvertAngle(euler.x), ConvertAngle(euler.y), ConvertAngle(euler.z));}/// <summary>/// 初始化相机位置/// </summary>public void ResetView(){if (minDistance > maxDistance)//如果最小距离大于最大距离 则将最小最大距离互换{maxDistance += minDistance;minDistance = maxDistance - minDistance;maxDistance -= minDistance;}if (rotateType == RotateType.VerticalOnly || rotateType == RotateType.Both) direction = -target.forward;else direction = new Vector3(1, 1, -1).normalized;disOffset = direction * (minDistance + maxDistance) / 2;transform.position = target.position + headOffset + disOffset;OriginDistance = disOffset.magnitude;disOffset = Vector3.zero;}public void SetTarget(Transform new_target){target = new_target;}private void OnDrawGizmos(){Gizmos.color = Color.red;Gizmos.DrawLine(target.position + headOffset, transform.position);Gizmos.color = Color.yellow;Gizmos.DrawWireSphere(target.position + headOffset, minDistance);Gizmos.DrawLine(target.position + headOffset + target.forward * minDistance, target.position + headOffset + target.forward * maxDistance);Gizmos.DrawLine(target.position + headOffset - target.forward * minDistance, target.position + headOffset - target.forward * maxDistance);Gizmos.DrawLine(target.position + headOffset + target.up * minDistance, target.position + headOffset + target.up * maxDistance);Gizmos.DrawLine(target.position + headOffset - target.up * minDistance, target.position + headOffset - target.up * maxDistance);Gizmos.DrawLine(target.position + headOffset + target.right * minDistance, target.position + headOffset + target.right * maxDistance);Gizmos.DrawLine(target.position + headOffset - target.right * minDistance, target.position + headOffset - target.right * maxDistance);Gizmos.DrawWireSphere(target.position + headOffset, maxDistance);}}

五: 第三人称相机跟随方法二

using System.Collections;using System.Collections.Generic;using UnityEngine;public class MyFollowCamera : MonoBehaviour{public float distanceAway=10;// z轴上的距离public float distanceUp=5; // 高度距离public float smooth=5;// 移动平滑值private GameObject hovercraft;// to store the hovercraftprivate Vector3 targetPosition;// 相机目标位置Transform follow;//跟随物体void Start(){//需要跟随的物体follow = GameObject.FindWithTag("Player").transform;}void LateUpdate(){//目标位置,由跟随物体的坐标+设置的高度+z轴的距离//减去follow.forward * distanceAway 为距离物体后背的距离 关于follow.forward的用法可以查看Transform.forward文章targetPosition = follow.position + Vector3.up * distanceUp - follow.forward * distanceAway;//从当前位置到目标位置 平滑过渡transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * smooth);//相机朝向transform.LookAt(follow);}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。