使用操纵杆基于相机面向的玩家运动



我正在开发一个离线FPS多人游戏。

当播放器旋转值为(0,0,0)时,播放器将朝方向完美移动。但是,我的问题是当我使用触摸输入旋转相机时。玩家还可以旋转他的脸,并按操纵杆按钮以移动玩家,但是玩家不应移动相机面向的方向。

我的玩家脚本

public class VirtualJoystick : MonoBehaviour, IDragHandler, IPointerUpHandler,IPointerDownHandler {
    private Image bgImg;
    private Image JoyStickImage;
    private Vector3 InputVector;
    private void Start(){
        bgImg = GetComponent<Image> ();
        JoyStickImage = transform.GetChild (0).GetComponent<Image> ();
    }
    public virtual void OnDrag(PointerEventData ped){
        Vector2 pos;
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle (bgImg.rectTransform, ped.position, ped.pressEventCamera, out pos)) {
            pos.x = (pos.x / bgImg.rectTransform.sizeDelta.x);
            pos.y = (pos.y / bgImg.rectTransform.sizeDelta.y);
            InputVector = new Vector3 (pos.x * 2 + 1, 0, pos.y * 2 - 1);
            InputVector = (InputVector.magnitude > 1) ? InputVector.normalized : InputVector;
            JoyStickImage.rectTransform.anchoredPosition = new Vector3 (InputVector.x * (bgImg.rectTransform.sizeDelta.x / 2.5f),
                                                                        InputVector.z * (bgImg.rectTransform.sizeDelta.y / 2.5f));

        }
    }
    public virtual void OnPointerDown(PointerEventData ped){
    
        OnDrag (ped);
    }
    public virtual void OnPointerUp(PointerEventData ped){
        InputVector = Vector3.zero;
        JoyStickImage.rectTransform.anchoredPosition = Vector3.zero;
    }
    public float Horizontal(){
        
        if (InputVector.x != 0) {
            return InputVector.x;
        } else {
            return Input.GetAxis ("Horizontal");
        }
        
    }
    public float Vertical(){
        
        if (InputVector.z != 0)
            return InputVector.z;
        else
            return Input.GetAxis ("Vertical");
        
    }
}

使用输入触摸

我的相机旋转脚本
public class SwipeCam : MonoBehaviour {
    private Vector3 firstPoint;
    private Vector3 secondPoint;
    private float xAngle = 0.0f;
    private float yAngle = 0.0f;
    private float xAngleTemp = 0.0f;
    private float yAngleTemp = 0.0f;
    void Start(){
        xAngle = 0.0f;
        yAngle = 0.0f;
        this.transform.rotation = Quaternion.Euler (yAngle, xAngle, 0.0f);
    }
    void Update() {
        
        if (Input.touchCount > 0) {
            
            for (int i = 0; i < Input.touchCount; i++) {
                Touch touch = Input.GetTouch (i);
                if (touch.position.x > Screen.width / 2) {
                    if (touch.phase == TouchPhase.Began) {
                         
                        firstPoint = Input.GetTouch (0).position;
                        xAngleTemp = xAngle;
                        yAngleTemp = yAngle;
                    }
                    if (touch.phase == TouchPhase.Moved) { 
                        secondPoint = Input.GetTouch (0).position;
                        xAngle = xAngleTemp + (secondPoint.x - firstPoint.x) * 180.0f / Screen.width;
                        yAngle = yAngleTemp + (secondPoint.y - firstPoint.y) * 180.0f / -Screen.height;
                        yAngle = Mathf.Clamp (yAngle, -30f, 30f);

                        this.transform.rotation = Quaternion.Euler (yAngle, xAngle, 0.0f);
                        this.gameObject.GetComponentInParent<FPScontroller> ().transform.rotation = Quaternion.Euler (0.0f, xAngle, 0.0f);
                        //this.gameObject.GetComponentInParent<FPScontroller> ().transform.rotation = Quaternion.LookRotation(Vector3.forward,Vector3.up);
                    
                    }
                }
            }
        }
    }
}

我应该在哪里更改代码以修复面向相机方向的播放器发行。

这是我的播放器脚本(fpscontroller.cs)

    public class FPScontroller : MonoBehaviour {
    
    // Should this script respond to input?
    public bool canControl = true;
    public GameObject lookObj; //This is root object that containc MainCamera, Weapons etc.
    public GameObject joystick;
    bool useFixedUpdate = false;
    
    //Check when run, walk or when can run or not
    [HideInInspector]
    public bool Running ;
    [HideInInspector]
    public bool Walking;
    [HideInInspector]
    public bool canRun;
    [HideInInspector]
    public Vector3 rorationDir;
    
    //Ladder variables
    private GameObject mainCamera = null;
    [HideInInspector]
    public bool onLadder = false;
    //private float ladderHopSpeed = 6.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 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;
    
    [HideInInspector]
    public bool inputRun = false;
    
    [HideInInspector]
    public bool inputCrouch = false;
    
    [HideInInspector]
    public bool inputProne = false;
    [System.Serializable]
    public class  FPScontrollerMovement {
        // The maximum horizontal speed when moving
        [HideInInspector]
        public float maxForwardSpeed = 10.0f;
        [HideInInspector]
        public float maxSidewaysSpeed = 10.0f;
        [HideInInspector]
        public float maxBackwardsSpeed = 10.0f;
        
        //Run and walk variables
        public float WalkSpeed = 6.0f;
        public float RunSpeed = 9.0f;
        //Crouch
        public bool canCrouch = true;
        public float CrouchSpeed = 3.0f;
        public float crouchHeight = 1.5f;
        public float crouchSmooth = 8;
        //prone
        public bool canProne = true;
        public float ProneSpeed = 1.5f;
        public float proneHeight = 0.7f;

        
        // 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;
        
        [HideInInspector]
        public bool enableGravity = 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 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 FPScontrollerMovement movement = new FPScontrollerMovement();
        void Awake () {
        if (GetComponent<NetworkView> ().isMine) {
            
        joystick = GameObject.Find ("Joystick");
        controller = gameObject.GetComponent<CharacterController>();
        standartHeight = controller.height;
        /*if(GameObject.FindWithTag("LookObject") != null){
            lookObj = GameObject.FindWithTag("LookObject");
        }*/
        centerY = controller.center.y;
        tr = transform;
    
        canRun = true;
        canStand = true;
        StartCoroutine(setupBools());
        }
    }
        void Update () {
        if (GetComponent<NetworkView> ().isMine) {
            if (!useFixedUpdate) {
                UpdateFunction ();
            }
        
            movement.velocity.x = joystick.GetComponent<VirtualJoystick> ().Horizontal () * 5f;
            movement.velocity.z = joystick.GetComponent<VirtualJoystick> ().Vertical () * 5f;

            //Run input
            if (Input.GetAxis ("Vertical") > 0.1f && inputRun && canRun && !onLadder && Walking) {
                if (canStand && canStandCrouch) {
                    OnRunning ();
                }
            } else {
                OffRunning ();
            }   
        
            //Check when walk or not
            if ((movement.velocity.x > 0.01f  || movement.velocity.z > 0.01f) || (movement.velocity.x < -0.01f || movement.velocity.z < -0.01f)) {
                RunAnimation1 ();
                Debug.Log ("Forward");
                Walking = true;
            }else if (movement.velocity.x > 0.01f) {
                Walking = true;
                Debug.Log ("Right");
            } else if (movement.velocity.x < -0.01f) {
                Walking = true;
                Debug.Log ("Left");
            } else {
                RunAnimation ();
                Walking = false;
            }
        
            if (!canControl)
                return;
        
            if (movement.canCrouch) {
                if (!onLadder) {    
                    Crouch ();
                }
            }
        
            if (movement.canProne) {
                if (!onLadder) {    
                    Prone ();
                }
            }
        
            if (onLadder) {
                grounded = false;
                crouch = false;
                prone = false;
            }
        
            if (!crouch && !prone && controller.height < standartHeight - 0.01f) {
                controller.height = Mathf.Lerp (controller.height, standartHeight, Time.deltaTime / movement.crouchSmooth);
                controller.center = new Vector3 (controller.center.x, Mathf.Lerp (controller.center.y, centerY, Time.deltaTime / movement.crouchSmooth), controller.center.z);
                lookObj.transform.localPosition = new Vector3 (lookObj.transform.localPosition.x, Mathf.Lerp (lookObj.transform.localPosition.y, standartHeight, Time.deltaTime / movement.crouchSmooth), lookObj.transform.localPosition.z);
            }
        }
    }
    void RunAnimation(){
        GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 0);
    }
    void RunAnimation1(){
        GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 1);
    }
    void RunAnimation2(){
        GetComponent<NetworkView> ().RPC ("SysnAnimation", RPCMode.All, 2);
    }
    [RPC]
    void SysnAnimation(int index){
        if (index == 0) {
            GetComponent<Animator> ().Play ("Idle Aim");
        } else if (index == 1) {
            GetComponent<Animator> ().Play ("Walk Aiming");
        } else if (index == 2) {
            GetComponent<Animator> ().Play ("Jump");
        }
    }
     void OnRunning (){
        Debug.Log ("Run");
        Running = true;
        movement.maxForwardSpeed = movement.RunSpeed;
        movement.maxSidewaysSpeed = movement.RunSpeed;
        //Make bigger extra height when player run to increase jump distance
        jumping.extraHeight = jumping.baseHeight + 0.15f;
    }
    
    void OffRunning (){
        Running = false;
        if(crouch || prone)
            return;
        movement.maxForwardSpeed = movement.WalkSpeed;
        movement.maxSidewaysSpeed = movement.WalkSpeed;
        movement.maxBackwardsSpeed = movement.WalkSpeed/2;
        //Change extraheight value to default when player walk
        jumping.extraHeight = jumping.baseHeight;
    }}

您的相机和操纵杆代码看起来不错,但这不是问题所在。

我假设您的播放器运动代码看起来像这样:

  • 获取输入x和y
  • X向前移动播放器,向前
  • 向前移动

在代码形式中,可能看起来像这样:

//returns the world-space direction that player wants to move
Vector3 GetDesiredMovement(float inputForward, float inputRight) {
    //get a vector pointing to player's right
    Vector3 dirRight = Camera.main.transform.right;
    dirRight.y = 0f;
    dirRight.Normalize();
    //get a vector pointing to player's front
    Vector3 dirForward = Camera.main.transform.forward;
    dirForward.y = 0f;
    dirForward.Normalize();
    //calculate desired movement based on input
    Vector3 desiredMovement = (dirForward * inputForward) + (dirRight * inputRight);
    desiredMovement.Normalize();
    return desiredMovement;
}

如果"正确"one_answers"向前"需要与场景中其他某些对象(例如相机)相对怎么办?它比您想象的要容易:只需直接从相机的变换组件中读取这些值。

您可以通过仅替换上述示例的两行来做到这一点:

Vector3 dirRight = Camera.main.transform.right;
Vector3 dirForward = Camera.main.transform.forward;

我解决了基于相机方向运动的问题。

在我的播放器脚本中,有两行阅读操纵杆输入:

    movement.velocity.x = joystick.GetComponent<VirtualJoystick> ().Horizontal () * 5f;
    movement.velocity.z = joystick.GetComponent<VirtualJoystick> ().Vertical () * 5f;`

我将它们更改为:

Vector3 DirectionVector = 
            new Vector3 (joystick.GetComponent<VirtualJoystick> ().Horizontal (), 0f, joystick.GetComponent<VirtualJoystick> ().Vertical ());
movement.velocity = transform.rotation * DirectionVector * 10f;

直接在运动矢量中添加操纵杆值。我只是将其乘以操纵杆输入向量并解决我的问题。

现在,玩家根据播放器旋转以及相机面对的位置移动。感谢大家的帮助。

相关内容

  • 没有找到相关文章

最新更新