unity3d 第一人称脚本_unity3d第一人称脚本 - CSDN
  • 1.把物体的坐标和摄像机的坐标设置成一样的,这样摄像机就在物体内部,就是第一人称的视角。 2.把摄像机拖拽进物体对象内,摄像机变成物体的子对象,这样摄像机就能跟着物体一起移动。 设置第三人称视角 ...

    设置第一人称视角

    1.把物体的坐标和摄像机的坐标设置成一样的,这样摄像机就在物体内部,就是第一人称的视角。
    在这里插入图片描述
    在这里插入图片描述
    2.把摄像机拖拽进物体对象内,摄像机变成物体的子对象,这样摄像机就能跟着物体一起移动。
    在这里插入图片描述


    设置第三人称视角

    方式一:(设置子对象)

    1.将摄像机拖拽到合适的角度上
    在这里插入图片描述
    2.把摄像机拖拽进物体对象,摄像机成为物体的子对象,这样摄像机就可以跟着物体一起移动
    在这里插入图片描述


    方式二:(脚本设置)

    1. 创建摄像机对象变量: private Animation animation;
    2. 获取主摄像机: mainCamera = Camera.main;
    3. 设置主摄像机的位置:主摄像机的位置 = 物体对象的位置 + 两者相对坐标差
      mainCamera.transform.position = transform.position + new Vector3(0, 11, -14);

    实现摄像机延迟移动效果

    Vector3.Lerp(主摄像机的位置, 主摄像机新位置, 时间差);
    mainCamera.transform.position = Vector3.Lerp( mainCamera.transform.position, transform.position + new Vector3(0, 11, -14), Time.deltaTime);

    代码实例

    public class Player01 : MonoBehaviour
    {
        //设置变量
        private Animation animation;
        private Camera mainCamera;
        float runSpeed;
        float angleSpeed;
        
        // Start is called before the first frame update
        void Start()
        {
            //获取动画对象
            animation = GetComponent<Animation>();
            //初始化移动速度和角速度
            runSpeed = 20f;
            angleSpeed = 120f;
            //获取主摄像机
            mainCamera = Camera.main;
        }
    
        // Update is called once per frame
        void Update()
        {
            //设置移动速度
            float forward = Input.GetAxisRaw("Vertical") * runSpeed;
            //设置角速度
            float rotation = Input.GetAxisRaw("Horizontal") * angleSpeed;
            //判断移动还是站立
            if (forward > 0)
            {
                //设置移动方向
                transform.Translate(0, 0, forward * Time.deltaTime);
                //播放跑步动画
                animation.CrossFade("run");
            }
            else
            {
                //播放站立动画
                animation.CrossFade("stand");
            }
    
            //设置移动方向
            transform.Rotate(0, rotation * Time.deltaTime, 0);
        }
    
        private void LateUpdate()
        {
            //主摄像机的位置 = 物体对象的位置 + 两者相对坐标差
            //mainCamera.transform.position = transform.position + new Vector3(0, 11, -14);
            //摄像机延迟移动效果
            mainCamera.transform.position = Vector3.Lerp(
                mainCamera.transform.position, 
                transform.position + new Vector3(0, 11, -14), 
                Time.deltaTime);
        }
    }
    
    展开全文
  • Unity第一人称控制脚本解析

    万次阅读 2016-10-05 22:24:23
    一个第一人称控制视角的脚本,类似官方提供的脚本格式,但是比官方的更通俗易懂。 没什么废话了,直接上代码: using UnityEngine; using System.Collections; //第一人称控制需要刚体和碰撞器 [RequireComponent...

    一个第一人称控制视角的脚本,类似官方提供的脚本格式,但是比官方的更通俗易懂。

    没什么废话了,直接上代码:

    using UnityEngine;
    using System.Collections;
    
    //第一人称控制需要刚体和碰撞器
    [RequireComponent(typeof(Rigidbody))]
    [RequireComponent(typeof(CapsuleCollider))]
    public class PlayerController : MonoBehaviour {
    
        //把运动相关的参数,独立出来
        [System.Serializable]
        public class MoveSetting
        {
            public float ForwarSpeed = 5f;
            public float BackSpeed = 3f;
            public float HorizonSpeed = 4f;
    
            public float RunValue = 2f;
            public float JumpForce = 50f;
        }
        //把视角相关的独立出来
        [System.Serializable]
        public class MouseLook
        {
            public float XSensitive = 2f;
            public float YSensitive = 2f;
        }
        
        public MoveSetting moveSet;
        public MouseLook CameraSet;
    
        //当前速度
        private float currentSpeed;
        //一段跳
        private bool m_jump;
        //二段跳
        private bool m_jump2;
    
        //第一人称,胶囊碰撞
        private CapsuleCollider m_capsule;
        //第一人称,刚体
        private Rigidbody m_rigidbody;
    
        private Camera m_camera;
        //相机的Transform(减少Update中transform的调用)
        private Transform m_camTrans;
        //主角的Transform
        private Transform m_chaTrans;
    
        摄像机欧拉角
        //private Vector3 m_camRotate;
        主角的欧拉角
        //private Vector3 m_chaRotate;
    
        //摄像机旋转四元数
        private Quaternion m_camQutation;
        //主角的旋转四元数
        private Quaternion m_chaQutation;
    
        //爬坡的速度曲线
        public AnimationCurve SlopCurve;
    
        //是否在地面上
        private bool m_isOnGround;
        //地面法线向量
        private Vector3 curGroundNormal;
    
        // Use this for initialization
        void Start () {
            m_capsule = GetComponent<CapsuleCollider>();
            m_rigidbody = GetComponent<Rigidbody>();
            
            m_camera = Camera.main;
            m_camTrans = m_camera.transform;
            m_chaTrans = transform;
    
            //初始化参数
            m_camQutation = m_camTrans.rotation;
            m_chaQutation = m_chaTrans.rotation;
        }
    	
    	// Update is called once per frame
    	void Update () {
            //视角转动
            RotateView();
    
            if (Input.GetKeyDown(KeyCode.Space))
            {
                m_jump = true;
            }
        }
    
        //物理的运动,需要放到FixedUpdate中,固定帧率0.02秒,可在Edit.time中修改
        void FixedUpdate()
        {
            DoMove();
        }
    
        //视图的旋转
        void RotateView()
        {
            float xRot = Input.GetAxis("Mouse Y") * CameraSet.YSensitive;
            float yRot = Input.GetAxis("Mouse X") * CameraSet.XSensitive;
    
            //欧拉角使用
            //{
            //    m_camRotate += new Vector3(-xRot, 0f, 0f);
            //需要LocalEulerAnglers,否则摄像机和胶囊体会同时对相机旋转起作用
            //    m_camTrans.localEulerAngles = m_camRotate;
            //    m_camRotate += new Vector3(0f, yRot, 0f);
            //    m_chaTrans.localEulerAngles = m_chaRotate;
            //}
    
            //四元数使用
            {
                m_camQutation *= Quaternion.Euler(-xRot, 0f, 0f);
                //限制旋转角度在【-90,90】内
                m_camQutation = ClampRotation(m_camQutation);
                m_camTrans.localRotation = m_camQutation;
    
                m_chaQutation *= Quaternion.Euler(0f, yRot, 0f);
                m_chaTrans.localRotation = m_chaQutation;
            }
        }
    
        void DoMove()
        {
            //检测地面
            CheckGround();
            //检测前后左右输入
            Vector2 input = GetInput();
            //更新当前速度,根据移动方向
            CaculateSpeed(input);
    
            //判断是否有移动的速度,没有就不给刚体施加力
            if ((Mathf.Abs(input.x) > float.Epsilon || Mathf.Abs(input.y) > float.Epsilon) && m_isOnGround)
            {
                //计算方向力
                Vector3 desireMove = m_camTrans.forward * input.y + m_camTrans.right * input.x;
                //力在地面投影的向量的(单位向量)
                desireMove = Vector3.ProjectOnPlane(desireMove, curGroundNormal).normalized;
                desireMove.x = desireMove.x * currentSpeed;
                desireMove.y = 0;
                desireMove.z = desireMove.z * currentSpeed;
    
                //当前速度不能大于规定速度(Magnitude方法,需要开平方根,使用sqr节省运算)
                if (m_rigidbody.velocity.sqrMagnitude < currentSpeed * currentSpeed)
                {
                    //给刚体施加(坡度计算后)的力
                    m_rigidbody.AddForce(desireMove * SlopeValue(), ForceMode.Impulse);
                }
            }
    
            
            if(m_isOnGround)
            {
                m_rigidbody.drag = 5f;
                jumpTime = 0;
                //一段跳
                if (m_jump)
                {
                    JumpUp();
                }
            }
            else
            {
                if(m_jump)
                {
                    jumpTime++;
                    //二段跳
                    if (jumpTime < 2)
                    {
                        JumpUp();
                    }
                }
            }
    
            m_jump = false;
        }
        int jumpTime = 0;
    
        //跳跃方法
        void JumpUp()
        {
            m_rigidbody.drag = 0f;
            //把刚体的上下方向的速度先归零
            m_rigidbody.velocity = new Vector3(m_rigidbody.velocity.x, 0f, m_rigidbody.velocity.z);
            m_rigidbody.AddForce(new Vector3(0, moveSet.JumpForce, 0), ForceMode.Impulse);
        }
    
        //检测方向键输入
        Vector2 GetInput()
        {
            Vector2 input = new Vector2
                (
                Input.GetAxis("Horizontal"),
                Input.GetAxis("Vertical")
                );
            //float horValue = Input.GetAxis("Horizontal");
            //float verValue = Input.GetAxis("Vertical");
    
            return input;
        }
        
        //计算 速度
        void CaculateSpeed(Vector2 _input)
        {
            currentSpeed = moveSet.ForwarSpeed;
    
            //横向移动
            if(Mathf.Abs(_input.x)>float.Epsilon)
            {
                currentSpeed = moveSet.HorizonSpeed;
            }
            //前进后退
            else if (_input.y < 0)
            {
                currentSpeed = moveSet.BackSpeed;
            }
            //Shift跑加速
            if (Input.GetKey(KeyCode.LeftShift))
            {
                currentSpeed *= moveSet.RunValue;
            }
            //Ctrl下蹲减速
        }
    
        //爬坡参数
        float SlopeValue()
        {
            float angle = Vector3.Angle(curGroundNormal,Vector3.up);
    
            float value = SlopCurve.Evaluate(angle);
            return value;
        }
    
        //检测地面
        void CheckGround()
        {
            RaycastHit hit;
    
            //球形碰撞检测(第9个方法)
            if (Physics.SphereCast(m_capsule.transform.position,m_capsule.radius,Vector3.down,out hit,((m_capsule.height / 2 - m_capsule.radius)+0.01f)))
            {
                //获取碰撞位置的发现向量
                curGroundNormal = hit.normal;
                m_isOnGround = true;
            }
            else
            {
                curGroundNormal = Vector3.up;
                m_isOnGround = false;
            }
        }
    
        void CheckBuffer()
        {
            RaycastHit hit;
            float speed = m_rigidbody.velocity.y;
            if (speed < 0)
            {
                if (Physics.SphereCast(m_capsule.transform.position, m_capsule.radius, Vector3.down, out hit, ((m_capsule.height / 2 - m_capsule.radius) + 1f)))
                {
                    speed *= 0.5f;
                    m_rigidbody.velocity = new Vector3(m_rigidbody.velocity.x, speed, m_rigidbody.velocity.z);
                }
            }
        }
    
        //四元数俯角,仰角限制
        Quaternion ClampRotation(Quaternion q)
        {
            //四元数的xyzw,分别除以同一个数,只改变模,不改变旋转
            q.x /= q.w;
            q.y /= q.w;
            q.z /= q.w;
            q.w = 1;
    
            /*给定一个欧拉旋转(X, Y, Z)(即分别绕x轴、y轴和z轴旋转X、Y、Z度),则对应的四元数为
    x = sin(Y/2)sin(Z/2)cos(X/2)+cos(Y/2)cos(Z/2)sin(X/2)
    y = sin(Y/2)cos(Z/2)cos(X/2)+cos(Y/2)sin(Z/2)sin(X/2)
    z = cos(Y/2)sin(Z/2)cos(X/2)-sin(Y/2)cos(Z/2)sin(X/2)
    w = cos(Y/2)cos(Z/2)cos(X/2)-sin(Y/2)sin(Z/2)sin(X/2)
             */
             
            //得到推导公式[欧拉角x=2*Aan(q.x)]
            float angle = 2 * Mathf.Rad2Deg * Mathf.Atan(q.x);
            //限制速度
            angle = Mathf.Clamp(angle,-90f,90f);
            //反推出q的新x的值
            q.x = Mathf.Tan(Mathf.Deg2Rad * (angle / 2));
    
            return q;
        }
    }
    



    展开全文
  • Unity3D 第一人称控制器 C#脚本

    千次阅读 2015-03-11 21:47:28
    欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,【狗刨学习网】unity极致学院,致力于打造业内unity3d培训、学习第一品牌。...


    <P> using UnityEngine;   
    using System.Collections;   </P>
    <P>/**   
    *  @Author : <A href="http://www.xuanyusong.com">www.xuanyusong.com</A>   
    */</P>
    <P>[RequireComponent(typeof(CharacterController))]   
    [AddComponentMenu("Character/Character Motor")]   </P>
    <P>public class CharacterMotor : MonoBehaviour {   
       
        // Does this script currently respond to input?   
        public bool canControl  = true;   
       
        public bool useFixedUpdate = true;   
       
        // For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.   
        // Very handy for organization!   
       
        // The current global direction we want the character to move in.   
        [System.NonSerialized]   
        public Vector3 inputMoveDirection = Vector3.zero;   
       
        // Is the jump button held down? We use this interface instead of checking   
        // for the jump button directly so this script can also be used by AIs.   
        [System.NonSerialized]   
        public bool inputJump  = false;   
       
        [System.Serializable]   
        public class CharacterMotorMovement   
        {   
            
            // The maximum horizontal speed when moving   
            public float maxForwardSpeed = 10.0f;   
            public float maxSidewaysSpeed = 10.0f;   
            public float maxBackwardsSpeed = 10.0f;   
            
            // Curve for multiplying speed based on slope (negative = downwards)   
            public AnimationCurve slopeSpeedMultiplier = new AnimationCurve(new Keyframe(-90, 1), new Keyframe(0, 1), new Keyframe(90, 0));   
            
            // How fast does the character change speeds?  Higher is faster.   
            public float maxGroundAcceleration = 30.0f;   
            public float maxAirAcceleration = 20.0f;   
            
            // The gravity for the character   
            public float gravity = 10.0f;   
            public float maxFallSpeed = 20.0f;   
            
            // For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.   
            // Very handy for organization!   
            
            // The last collision flags returned from controller.Move   
            [System.NonSerialized]   
            public CollisionFlags collisionFlags;   
            
            // We will keep track of the character's current velocity,   
            [System.NonSerialized]   
            public Vector3 velocity;   
            
            // This keeps track of our current velocity while we're not grounded   
            [System.NonSerialized]   
            public Vector3 frameVelocity = Vector3.zero;   
            
            [System.NonSerialized]   
            public Vector3 hitPoint = Vector3.zero;   
            
            [System.NonSerialized]   
            public Vector3 lastHitPoint = new Vector3(Mathf.Infinity, 0, 0);   
        }   
       
        public CharacterMotorMovement movement = new CharacterMotorMovement();   
       
        public enum MovementTransferOnJump {   
            None, // The jump is not affected by velocity of floor at all.   
            InitTransfer, // Jump gets its initial velocity from the floor, then gradualy comes to a stop.   
            PermaTransfer, // Jump gets its initial velocity from the floor, and keeps that velocity until landing.   
            PermaLocked // Jump is relative to the movement of the last touched floor and will move together with that floor.   
        }   
       
        // We will contain all the jumping related variables in one helper class for clarity.      
        [System.Serializable]   
        public class CharacterMotorJumping {   
            // Can the character jump?   
            public bool enabled = true;   
            
            // How high do we jump when pressing jump and letting go immediately   
            public float baseHeight = 1.0f;   
            
            // We add extraHeight units (meters) on top when holding the button down longer while jumping   
            public float extraHeight = 4.1f;   
            
            // How much does the character jump out perpendicular to the surface on walkable surfaces?   
            // 0 means a fully vertical jump and 1 means fully perpendicular.   
            public float perpAmount  = 0.0f;   
            
            // How much does the character jump out perpendicular to the surface on too steep surfaces?   
            // 0 means a fully vertical jump and 1 means fully perpendicular.   
            public float steepPerpAmount = 0.5f;   
            
            // For the next variables, @System.NonSerialized tells Unity to not serialize the variable or show it in the inspector view.   
            // Very handy for organization!   
            
            // Are we jumping? (Initiated with jump button and not grounded yet)   
            // To see if we are just in the air (initiated by jumping OR falling) see the grounded variable.   
            [System.NonSerialized]   
            public bool jumping = false;   
            
            [System.NonSerialized]   
            public bool holdingJumpButton = false;   
            
            // the time we jumped at (Used to determine for how long to apply extra jump power after jumping.)   
            [System.NonSerialized]   
            public float lastStartTime = 0.0f;   
            
            [System.NonSerialized]   
            public float lastButtonDownTime = -100f;   
            
            [System.NonSerialized]   
            public Vector3 jumpDir = Vector3.up;   
        }   
       
        public CharacterMotorJumping  jumping = new CharacterMotorJumping();   
       
        [System.Serializable]   
        public class CharacterMotorMovingPlatform {   
            public bool enabled = true;   
            
            public MovementTransferOnJump movementTransfer = MovementTransferOnJump.PermaTransfer;   
            
            [System.NonSerialized]   
            public Transform hitPlatform;   
            
            [System.NonSerialized]   
            public Transform activePlatform;   
            
            [System.NonSerialized]   
            public Vector3 activeLocalPoint;   
            
            [System.NonSerialized]   
            public Vector3 activeGlobalPoint;   
            
            [System.NonSerialized]   
            public Quaternion activeLocalRotation;   
            
            [System.NonSerialized]   
            public Quaternion activeGlobalRotation;   
            
            [System.NonSerialized]   
            public Matrix4x4 lastMatrix;   
            
            [System.NonSerialized]   
            public Vector3 platformVelocity;   
            
            [System.NonSerialized]   
            public bool newPlatform;   
        }   
       
        public CharacterMotorMovingPlatform movingPlatform  = new CharacterMotorMovingPlatform();   
       
        [System.Serializable]   
        public class CharacterMotorSliding {   
            // Does the character slide on too steep surfaces?   
            public bool enabled = true;   
            
            // How fast does the character slide on steep surfaces?   
            public float slidingSpeed  = 15f;   
            
            // How much can the player control the sliding direction?   
            // If the value is 0.5 the player can slide sideways with half the speed of the downwards sliding speed.   
            public float sidewaysControl = 1.0f;   
            
            // How much can the player influence the sliding speed?   
            // If the value is 0.5 the player can speed the sliding up to 150% or slow it down to 50%.   
            public float speedControl  = 0.4f;   
        }   
       
        public CharacterMotorSliding sliding  = new CharacterMotorSliding();   
       
        [System.NonSerialized]   
        public bool grounded = true;   
       
        [System.NonSerialized]   
        public Vector3 groundNormal = Vector3.zero;   
       
        private Vector3  lastGroundNormal = Vector3.zero;   
       
        private Transform tr;   
       
        private CharacterController  controller ;   
       
        void Awake () {   
            controller = GetComponent <CharacterController>();   
            tr = transform;   
        }   
       
        private void UpdateFunction () {   
            // We copy the actual velocity into a temporary variable that we can manipulate.   
            Vector3 velocity  = movement.velocity;   
            
            // Update velocity based on input   
            velocity = ApplyInputVelocityChange(velocity);   
            
            // Apply gravity and jumping force   
            velocity = ApplyGravityAndJumping (velocity);   
            
            // Moving platform support   
            Vector3 moveDistance  = Vector3.zero;   
            if (MoveWithPlatform()) {   
                Vector3 newGlobalPoint  = movingPlatform.activePlatform.TransformPoint(movingPlatform.activeLocalPoint);   
                moveDistance = (newGlobalPoint - movingPlatform.activeGlobalPoint);   
                if (moveDistance != Vector3.zero)   
                    controller.Move(moveDistance);   
                
                // Support moving platform rotation as well:   
                Quaternion newGlobalRotation  = movingPlatform.activePlatform.rotation * movingPlatform.activeLocalRotation;   
                Quaternion rotationDiff  = newGlobalRotation * Quaternion.Inverse(movingPlatform.activeGlobalRotation);   
                
                var yRotation = rotationDiff.eulerAngles.y;   
                if (yRotation != 0) {   
                    // Prevent rotation of the local up vector   
                    tr.Rotate(0, yRotation, 0);   
                }   
            }   
            
            // Save lastPosition for velocity calculation.   
            Vector3 lastPosition  = tr.position;   
            
            // We always want the movement to be framerate independent.  Multiplying by Time.deltaTime does this.   
            Vector3 currentMovementOffset = velocity * Time.deltaTime;   
            
            // Find out how much we need to push towards the ground to avoid loosing grouning   
            // when walking down a step or over a sharp change in slope.   
            float pushDownOffset  = Mathf.Max(controller.stepOffset, new Vector3(currentMovementOffset.x, 0, currentMovementOffset.z).magnitude);   
            if (grounded)   
                currentMovementOffset -= pushDownOffset * Vector3.up;   
            
            // Reset variables that will be set by collision function   
            movingPlatform.hitPlatform = null;   
            groundNormal = Vector3.zero;   
            
            // Move our character!   
            movement.collisionFlags = controller.Move (currentMovementOffset);   
            
            movement.lastHitPoint = movement.hitPoint;   
            lastGroundNormal = groundNormal;   
            
            if (movingPlatform.enabled && movingPlatform.activePlatform != movingPlatform.hitPlatform) {   
                if (movingPlatform.hitPlatform != null) {   
                    movingPlatform.activePlatform = movingPlatform.hitPlatform;   
                    movingPlatform.lastMatrix = movingPlatform.hitPlatform.localToWorldMatrix;   
                    movingPlatform.newPlatform = true;   
                }   
            }   
            
            // Calculate the velocity based on the current and previous position.     
            // This means our velocity will only be the amount the character actually moved as a result of collisions.   
            Vector3 oldHVelocity  = new Vector3(velocity.x, 0, velocity.z);   
            movement.velocity = (tr.position - lastPosition) / Time.deltaTime;   
            Vector3 newHVelocity  = new Vector3(movement.velocity.x, 0, movement.velocity.z);   
            
            // The CharacterController can be moved in unwanted directions when colliding with things.   
            // We want to prevent this from influencing the recorded velocity.   
            if (oldHVelocity == Vector3.zero) {   
                movement.velocity = new Vector3(0, movement.velocity.y, 0);   
            }   
            else {   
                float projectedNewVelocity  = Vector3.Dot(newHVelocity, oldHVelocity) / oldHVelocity.sqrMagnitude;   
                movement.velocity = oldHVelocity * Mathf.Clamp01(projectedNewVelocity) + movement.velocity.y * Vector3.up;   
            }   
            
            if (movement.velocity.y < velocity.y - 0.001) {   
                if (movement.velocity.y < 0) {   
                    // Something is forcing the CharacterController down faster than it should.   
                    // Ignore this   
                    movement.velocity.y = velocity.y;   
                }   
                else {   
                    // The upwards movement of the CharacterController has been blocked.   
                    // This is treated like a ceiling collision - stop further jumping here.   
                    jumping.holdingJumpButton = false;   
                }   
            }   
            
            // We were grounded but just loosed grounding   
            if (grounded && !IsGroundedTest()) {   
                grounded = false;   
                
                // Apply inertia from platform   
                if (movingPlatform.enabled &&   
                    (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer ||   
                 movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer)   
                    ) {   
                    movement.frameVelocity = movingPlatform.platformVelocity;   
                    movement.velocity += movingPlatform.platformVelocity;   
                }   
                
                SendMessage("OnFall", SendMessageOptions.DontRequireReceiver);   
                // We pushed the character down to ensure it would stay on the ground if there was any.   
                // But there wasn't so now we cancel the downwards offset to make the fall smoother.   
                tr.position += pushDownOffset * Vector3.up;   
            }   
            // We were not grounded but just landed on something   
            else if (!grounded && IsGroundedTest()) {   
                grounded = true;   
                jumping.jumping = false;   
                SubtractNewPlatformVelocity();   
                
                SendMessage("OnLand", SendMessageOptions.DontRequireReceiver);   
            }   
            
            // Moving platforms support   
            if (MoveWithPlatform()) {   
                // Use the center of the lower half sphere of the capsule as reference point.   
                // This works best when the character is standing on moving tilting platforms.   
                movingPlatform.activeGlobalPoint = tr.position + Vector3.up * (controller.center.y - controller.height*0.5f + controller.radius);   
                movingPlatform.activeLocalPoint = movingPlatform.activePlatform.InverseTransformPoint(movingPlatform.activeGlobalPoint);   
                
                // Support moving platform rotation as well:   
                movingPlatform.activeGlobalRotation = tr.rotation;   
                movingPlatform.activeLocalRotation = Quaternion.Inverse(movingPlatform.activePlatform.rotation) * movingPlatform.activeGlobalRotation;   
            }   
        }   
       
        void FixedUpdate () {   
            if (movingPlatform.enabled) {   
                if (movingPlatform.activePlatform != null) {   
                    if (!movingPlatform.newPlatform) {   
                        Vector3 lastVelocity  = movingPlatform.platformVelocity;   
                        
                        movingPlatform.platformVelocity = (   
                                                           movingPlatform.activePlatform.localToWorldMatrix.MultiplyPoint3x4(movingPlatform.activeLocalPoint)   
                                                           - movingPlatform.lastMatrix.MultiplyPoint3x4(movingPlatform.activeLocalPoint)   
                                                           ) / Time.deltaTime;   
                    }   
                    movingPlatform.lastMatrix = movingPlatform.activePlatform.localToWorldMatrix;   
                    movingPlatform.newPlatform = false;   
                }   
                else {   
                    movingPlatform.platformVelocity = Vector3.zero;   
                }   
            }   
            
            if (useFixedUpdate)   
                UpdateFunction();   
        }   
       
        void Update () {   
            if (!useFixedUpdate)   
                UpdateFunction();   
        }   
       
        private Vector3 ApplyInputVelocityChange (Vector3 velocity) {      
            if (!canControl)   
                inputMoveDirection = Vector3.zero;   
            
            // Find desired velocity   
            Vector3 desiredVelocity;   
            if (grounded && TooSteep()) {   
                // The direction we're sliding in   
                desiredVelocity = new Vector3(groundNormal.x, 0, groundNormal.z).normalized;   
                // Find the input movement direction projected onto the sliding direction   
                var projectedMoveDir = Vector3.Project(inputMoveDirection, desiredVelocity);   
                // Add the sliding direction, the spped control, and the sideways control vectors   
                desiredVelocity = desiredVelocity + projectedMoveDir * sliding.speedControl + (inputMoveDirection - projectedMoveDir) * sliding.sidewaysControl;   
                // Multiply with the sliding speed   
                desiredVelocity *= sliding.slidingSpeed;   
            }   
            else
                desiredVelocity = GetDesiredHorizontalVelocity();   
            
            if (movingPlatform.enabled && movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer) {   
                desiredVelocity += movement.frameVelocity;   
                desiredVelocity.y = 0;   
            }   
            
            if (grounded)   
                desiredVelocity = AdjustGroundVelocityToNormal(desiredVelocity, groundNormal);   
            else
                velocity.y = 0;   
            
            // Enforce max velocity change   
            float maxVelocityChange  = GetMaxAcceleration(grounded) * Time.deltaTime;   
            Vector3 velocityChangeVector  = (desiredVelocity - velocity);   
            if (velocityChangeVector.sqrMagnitude > maxVelocityChange * maxVelocityChange) {   
                velocityChangeVector = velocityChangeVector.normalized * maxVelocityChange;   
            }   
            // If we're in the air and don't have control, don't apply any velocity change at all.   
            // If we're on the ground and don't have control we do apply it - it will correspond to friction.   
            if (grounded || canControl)   
                velocity += velocityChangeVector;   
            
            if (grounded) {   
                // When going uphill, the CharacterController will automatically move up by the needed amount.   
                // Not moving it upwards manually prevent risk of lifting off from the ground.   
                // When going downhill, DO move down manually, as gravity is not enough on steep hills.   
                velocity.y = Mathf.Min(velocity.y, 0);   
            }   
            
            return velocity;   
        }   
       
        private Vector3 ApplyGravityAndJumping (Vector3 velocity) {   
            
            if (!inputJump || !canControl) {   
                jumping.holdingJumpButton = false;   
                jumping.lastButtonDownTime = -100;   
            }   
            
            if (inputJump && jumping.lastButtonDownTime < 0 && canControl)   
                jumping.lastButtonDownTime = Time.time;   
            
            if (grounded)   
                velocity.y = Mathf.Min(0, velocity.y) - movement.gravity * Time.deltaTime;   
            else {   
                velocity.y = movement.velocity.y - movement.gravity * Time.deltaTime;   
                
                // When jumping up we don't apply gravity for some time when the user is holding the jump button.   
                // This gives more control over jump height by pressing the button longer.   
                if (jumping.jumping && jumping.holdingJumpButton) {   
                    // Calculate the duration that the extra jump force should have effect.   
                    // If we're still less than that duration after the jumping time, apply the force.   
                    if (Time.time < jumping.lastStartTime + jumping.extraHeight / CalculateJumpVerticalSpeed(jumping.baseHeight)) {   
                        // Negate the gravity we just applied, except we push in jumpDir rather than jump upwards.   
                        velocity += jumping.jumpDir * movement.gravity * Time.deltaTime;   
                    }   
                }   
                
                // Make sure we don't fall any faster than maxFallSpeed. This gives our character a terminal velocity.   
                velocity.y = Mathf.Max (velocity.y, -movement.maxFallSpeed);   
            }   
            
            if (grounded) {   
                // Jump only if the jump button was pressed down in the last 0.2 seconds.   
                // We use this check instead of checking if it's pressed down right now   
                // because players will often try to jump in the exact moment when hitting the ground after a jump   
                // and if they hit the button a fraction of a second too soon and no new jump happens as a consequence,   
                // it's confusing and it feels like the game is buggy.   
                if (jumping.enabled && canControl && (Time.time - jumping.lastButtonDownTime < 0.2)) {   
                    grounded = false;   
                    jumping.jumping = true;   
                    jumping.lastStartTime = Time.time;   
                    jumping.lastButtonDownTime = -100;   
                    jumping.holdingJumpButton = true;   
                   
                    // Calculate the jumping direction   
                    if (TooSteep())   
                        jumping.jumpDir = Vector3.Slerp(Vector3.up, groundNormal, jumping.steepPerpAmount);   
                    else
                        jumping.jumpDir = Vector3.Slerp(Vector3.up, groundNormal, jumping.perpAmount);   
                   
                    // Apply the jumping force to the velocity. Cancel any vertical velocity first.   
                    velocity.y = 0;   
                    velocity += jumping.jumpDir * CalculateJumpVerticalSpeed (jumping.baseHeight);   
                   
                    // Apply inertia from platform   
                    if (movingPlatform.enabled &&   
                        (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer ||   
                     movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer)   
                        ) {   
                        movement.frameVelocity = movingPlatform.platformVelocity;   
                        velocity += movingPlatform.platformVelocity;   
                    }   
                   
                    SendMessage("OnJump", SendMessageOptions.DontRequireReceiver);   
                }   
                else {   
                    jumping.holdingJumpButton = false;   
                }   
            }   
            
            return velocity;   
        }   
       
        void OnControllerColliderHit (ControllerColliderHit hit) {   
            if (hit.normal.y > 0 && hit.normal.y > groundNormal.y && hit.moveDirection.y < 0) {   
                if ((hit.point - movement.lastHitPoint).sqrMagnitude > 0.001 || lastGroundNormal == Vector3.zero)   
                    groundNormal = hit.normal;   
                else
                    groundNormal = lastGroundNormal;   
                
                movingPlatform.hitPlatform = hit.collider.transform;   
                movement.hitPoint = hit.point;   
                movement.frameVelocity = Vector3.zero;   
            }   
        }   
       
        private IEnumerator SubtractNewPlatformVelocity () {   
            // When landing, subtract the velocity of the new ground from the character's velocity   
            // since movement in ground is relative to the movement of the ground.   
            if (movingPlatform.enabled &&   
                (movingPlatform.movementTransfer == MovementTransferOnJump.InitTransfer ||   
             movingPlatform.movementTransfer == MovementTransferOnJump.PermaTransfer)   
                ) {   
                // If we landed on a new platform, we have to wait for two FixedUpdates   
                // before we know the velocity of the platform under the character   
                if (movingPlatform.newPlatform) {   
                    Transform platform  = movingPlatform.activePlatform;   
                    yield return new WaitForFixedUpdate();   
                    yield return new WaitForFixedUpdate();   
                    if (grounded && platform == movingPlatform.activePlatform)   
                        yield return 1;   
                }   
                movement.velocity -= movingPlatform.platformVelocity;   
            }   
        }   
       
        private bool MoveWithPlatform () {   
            return (   
                    movingPlatform.enabled   
                    && (grounded || movingPlatform.movementTransfer == MovementTransferOnJump.PermaLocked)   
                    && movingPlatform.activePlatform != null
                    );   
        }   
       
        private Vector3 GetDesiredHorizontalVelocity () {   
            // Find desired velocity   
            Vector3 desiredLocalDirection  = tr.InverseTransformDirection(inputMoveDirection);   
            float maxSpeed  = MaxSpeedInDirection(desiredLocalDirection);   
            if (grounded) {   
                // Modify max speed on slopes based on slope speed multiplier curve   
                var movementSlopeAngle = Mathf.Asin(movement.velocity.normalized.y)  * Mathf.Rad2Deg;   
                maxSpeed *= movement.slopeSpeedMultiplier.Evaluate(movementSlopeAngle);   
            }   
            return tr.TransformDirection(desiredLocalDirection * maxSpeed);   
        }   
       
        private Vector3 AdjustGroundVelocityToNormal (Vector3 hVelocity, Vector3 groundNormal) {   
            Vector3 sideways  = Vector3.Cross(Vector3.up, hVelocity);   
            return Vector3.Cross(sideways, groundNormal).normalized * hVelocity.magnitude;   
        }   
       
        private bool IsGroundedTest () {   
            return (groundNormal.y > 0.01);   
        }   
       
        float GetMaxAcceleration (bool grounded) {   
            // Maximum acceleration on ground and in air   
            if (grounded)   
                return movement.maxGroundAcceleration;   
            else
                return movement.maxAirAcceleration;   
        }   
       
        float CalculateJumpVerticalSpeed (float targetJumpHeight) {   
            // From the jump height and gravity we deduce the upwards speed   
            // for the character to reach at the apex.   
            return Mathf.Sqrt (2 * targetJumpHeight * movement.gravity);   
        }   
       
        bool IsJumping () {   
            return jumping.jumping;   
        }   
       
        bool IsSliding () {   
            return (grounded && sliding.enabled && TooSteep());   
        }   
       
        bool IsTouchingCeiling () {   
            return (movement.collisionFlags & CollisionFlags.CollidedAbove) != 0;   
        }   
       
        bool IsGrounded () {   
            return grounded;   
        }   
       
        bool TooSteep () {   
            return (groundNormal.y <= Mathf.Cos(controller.slopeLimit * Mathf.Deg2Rad));   
        }   
       
        Vector3 GetDirection () {   
            return inputMoveDirection;   
        }   
       
        void  SetControllable (bool controllable) {   
            canControl = controllable;   
        }   
       
        // Project a direction onto elliptical quater segments based on forward, sideways, and backwards speed.   
        // The function returns the length of the resulting vector.   
        float MaxSpeedInDirection (Vector3 desiredMovementDirection) {   
            if (desiredMovementDirection == Vector3.zero)   
                return 0;   
            else {   
                float zAxisEllipseMultiplier = (desiredMovementDirection.z > 0 ? movement.maxForwardSpeed : movement.maxBackwardsSpeed) / movement.maxSidewaysSpeed;   
                Vector3 temp = new Vector3(desiredMovementDirection.x, 0, desiredMovementDirection.z / zAxisEllipseMultiplier).normalized;   
                float length = new Vector3(temp.x, 0, temp.z * zAxisEllipseMultiplier).magnitude * movement.maxSidewaysSpeed;   
                return length;   
            }   
        }   
       
        void SetVelocity (Vector3 velocity) {   
            grounded = false;   
            movement.velocity = velocity;   
            movement.frameVelocity = Vector3.zero;   
            SendMessage("OnExternalVelocity");   
        }   
       
        // Require a character controller to be attached to the same game object   
       
        <A>//@script</A> RequireComponent (CharacterController)   
        <A>//@script</A> AddComponentMenu ("Character/Character Motor")   
       
    }</P>






    展开全文
  • Unity 视角 第一人称脚本 MouseLook

    万次阅读 2014-06-30 13:09:11
    研究了一下第一人称控制器后,把它的

    写在前面:

    研究了一下 unity 的第一人称控制器后,把他自带的 Mouse Look 脚本做了简化。这样代码看上去更简单明了。记录下来,以备以后再用到。所以,这是一个没啥营养的文。


    第一人称视角实验:

    1,搭建一个实验场景:1个摄像机,1个平面,1个正方体(作为参照物),1个胶囊体(作为主角),1个点光源。

    2,把摄像机放到胶囊体上,摆好高度(相当于第一人称的眼睛),如下图:


    3,新建一个脚本,作为相机的控制脚本(其实这个脚本就是Mouse Look.cs 脚本,做了删减)。脚本如下:

    using UnityEngine;
    using System.Collections;
    
    public class FirstView : MonoBehaviour {
    
    	//方向灵敏度
    	public float sensitivityX = 10F; 
    	public float sensitivityY = 10F; 
    	
    	//上下最大视角(Y视角)
    	public float minimumY = -60F;
    	public float maximumY = 60F;
    	
    	float rotationY = 0F;
    	
    	void Update ()
    	{
    		//根据鼠标移动的快慢(增量), 获得相机左右旋转的角度(处理X)
    		float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;
    		
    		//根据鼠标移动的快慢(增量), 获得相机上下旋转的角度(处理Y)
    		rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
    		//角度限制. rotationY小于min,返回min. 大于max,返回max. 否则返回value 
    		rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
    		
    		//总体设置一下相机角度
    		transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0); 
    	}
    	
    	void Start ()
    	{
    		// Make the rigid body not change rotation
    		if (rigidbody)
    			rigidbody.freezeRotation = true;
    	}
    }

    4,把这个脚本放到相机上。ok。


    总结:视角的控制,其实很简单。主要是控制:旋转、以及输入设备的增量(比如,鼠标移动的快,视角转动的也要快)。




    展开全文
  • Unity3D中的人称镜头的脚本控制

    万次阅读 2014-05-30 05:08:48
    好久没有敲Blog了,谢谢大家的留言、关注、私信等支持,但是我好像已经没有办法让自己继续写以前的博客系列了,因为我发现网上关于unity3D的内容太少了,所以我无法自拔地想写U3D相关的文章!!! 人称视角 ...
  • Unity第一人称

    2020-07-30 23:32:10
    Unity第一人称
  • Unity第一人称和第三人称视角脚本

    千次阅读 2015-07-29 15:02:01
    Unity第一人称和第三人称视角 第一人称视角 public class FirstView : MonoBehaviour { //要相机跟随的GameObject public Transform m_target; //鼠标敏度 public float mousesSensity = 10F; //上下...
  • unity3D第一人称射击游戏(推荐)

    千次阅读 2014-05-08 12:42:20
    unity3d第一人称射击游戏(推荐) 第一部分:简介   这个教程中,我们详细了解下如何制作一个简单的第一人称射击游戏(FPS)。其中将介绍一些基本的3D游戏编程的概念和一些关于怎样如游戏程序员般思考的技巧。 ...
  • [Unity3d]第一人称和第三人称视角完美切换

    万次阅读 多人点赞 2019-10-29 14:53:33
    最近一直在搞3D漫游,在第一人称和第三人称视角切换碰到些问题,视角的例子我是导入的官方的character controller包,不得不佩服官方脚本语言的写法,看了一下写的很完美,新手估计比较难看懂,里面涉及到一些角度,...
  • //人称摄像机更随 var cameraTransform : Transform; //跟随相机 private var _target : Transform; //跟随物体 // The distance in the x-z plane to the target var distance = 7.0; //相机...
  • unity3D 第一人称简单射击示例

    千次阅读 2018-06-08 00:09:20
    unity5实战三章,慢慢学习放两个东西个是玩家,主摄像机附在上面,配上Mouselook.cs,FPSInput.cs使其能响应键盘移动跟鼠标移动Mouselook.cs,FPSInput.cs的实现前面有个是敌人,附上Reactive.cs受击反馈脚本,...
  • unity3D 第一人称射击游戏

    千次阅读 2015-01-26 23:13:27
    今天和·1昨天学习了《第一人称射击游戏》 现在来做一个总结: 首先是对周围墙体、地面加上一个碰撞检测体:Msh Collider(主要作用就是为了是其他物体gameobject对象无穿越它) 再在上面加一个Navigation...
  • - 使用wasd控制人物的前后左右...创建脚本MoveController1 using System.Collections; using System.Collections.Generic; using System.IO; using System.Threading; using UnityEngine; public class MoveCon...
  • Unity3D第人称摄像机

    千次阅读 2018-10-17 16:40:34
    创建个名为CameraBase的空物体,把该物体移动至人物模型的上半身的中央处,世界坐标为(0, 1.35, 0),这个物体相当于是摄像机的基准点。随后我把摄像机设为CameraBase的子物体,把摄像机拖到人物模型的后方,...
  • 本项目实战课程首先通过已完成的案例介绍项目中的功能,接着分模块进行功能的开发实现,在前半部分课程,通过角色控制器实现角色的控制,接着完成了相机的视角跟随功能,及场景元素功能的开发,后半部分课程主要是对...
  • unity3d 4.x里,找到挂载在第一人称上的"Character Motor"脚本。把脚本下边的 movement里的Gravity值设为0 即可。如下图所示:
  • Unity3D第人称Camera视角旋转实现

    千次阅读 2018-08-11 10:43:57
    Unity3D第人称Camera视角旋转,实现对player观察的实现,效果图如下(player and Scene 有点lou): 内容知识总结: Input.GetAxis():该方法用于在Unity3D中根据坐标轴名称返回虚拟坐标系中的值,通常情况下...
  • Unity3D的场景中需要漫游时,通常会使用Unity 3D的标准资源包中的Characters 资源,其中的 FirstPersonController 预制提供了完整的角色控制功能,使用起来十分方便,但是角色资源包的内容过多,比如:在只使用...
  • Unity第人称视角摄像机、跟随与球面旋转逻辑释义图解分析Unity C#代码 逻辑释义 【关键transform】 1[玩家] 2[注视目标点] 3[摄像机] [摄像机]跟随[注视目标点],[注视目标点]跟随[玩家] 【看向注视目标点】 ...
1 2 3 4 5 ... 20
收藏数 1,225
精华内容 490
关键字:

unity3d 第一人称脚本