1. 程式人生 > 其它 >移動端實現同時移動搖桿和攝像機旋轉(雙/多指觸控)

移動端實現同時移動搖桿和攝像機旋轉(雙/多指觸控)

技術標籤:unity3d移動開發安卓androidc#

網上找了好久都沒有找到具體的實現方案,無奈之下就自己琢磨,完善一下這空白的部分。

1. 目標需求:

搖桿控制人物移動和射擊/跳躍,用的是easytouch 3.1.6 ,這個版本好像要配合指令碼來用。(連結放在最下面)
攝像機旋轉,要另外用指令碼寫,這個寫的挺簡陋的,(還請大佬多多指點)。
實現效果:
在這裡插入圖片描述

2. 實現搖桿

  1. 將Easytouch匯入
  2. 在開啟頂部的工具欄新增搖桿/按鈕
    在這裡插入圖片描述
    adding a new joystick新增搖桿,另一個是按鈕,這裡我們新增搖桿。
  3. 設定搖桿屬性(就是配置一下指令碼)
    在這裡插入圖片描述
    這樣差不多了,其他的按照需求改。
  4. 為主角新增角色控制器
    在這裡插入圖片描述

3. 搖桿指令碼(新增給需要移動的物體)

這裡只考慮移動,不管攝像機是否跟隨:
自行放到類裡面即可:(有的變數要自己新增和初始化)

void OnEnable()  
    {    
           EasyJoystick.On_JoystickMove += OnJoystickMove;  
//新增事件,當搖桿移動時會自行呼叫下面的OnJoystickMove函式
    }  
  //  此函式是搖桿移動中所要處理的事
  void OnJoystickMove(MovingJoystick move)  
      {    
                 if (move.
joystickName != "My joystick") //這裡的名字就是剛才改的名字,不對應就不能用 { return; } float PositionX = move.joystickAxis.x; // 獲取搖桿偏移搖桿中心的x座標 float PositionY = move.joystickAxis.y; // 獲取搖桿偏移搖桿中心的y座標 if (PositionY != 0 || PositionX !=
0) { Vector3 motion = Vector3.zero; motion.x = PositionX * Time.deltaTime * m_speed; motion.z = PositionY * Time.deltaTime * m_speed; /*m_ch是主角的角色控制器*/m_ch.Move(m_tf.TransformDirection(motion)); // 主角移動 前後始終對應z軸,左右對應x軸 //你還可以放你在控制遙感/移動時想觸發的程式碼 } m_fingerController.isTouchJoystick = true; //,在移動,傳遞給攝像機,保證單觸屏時正常移動(不會旋轉相機),這個可以先不管 } }

現在主角應該可以前後左右移動了,在場景檢視中可以看到,但是攝像機還不會跟隨,也不會旋轉;

4. 攝像機跟隨:

在當前指令碼引入你打算跟隨的攝像機m_ctf;
然後再update中加入這一行程式碼:
m_ctf.position = new Vector3(m_tf.position.x, m_tf.position.y + Height, m_tf.position.z); //攝像機移動,m_tf是主角的transform
完事;

5. 攝像機旋轉:

這個方法有很多,但是我暫時只想到用Input.Gettouch,然後逐一列舉情況的辦法;
手機上觸屏的情況無非有3種:
(1)單觸移動
(2)單觸旋轉
(3)雙觸移動+旋轉

這是基本要了解的幾個屬性:
在這裡插入圖片描述
在攝像機中新增指令碼:
關鍵程式碼邏輯:

  1. Update中:判斷是單觸還是雙觸,如果是單觸判斷是否是搖桿的,如果不是才能攝像機旋轉,
    如果是雙觸,要判斷touch的索引是0還是1,這裡用Input.GetTouch(1).position判斷是左右半屏,左邊一般就是移動,右邊的是旋轉,當然也不是很準確,如果有其他方法再補充
  2. lateUpdate中:
    update中獲取了x,y的增量,當然有最大小值限制,這裡用他們來進行旋轉:

6. 完整的指令碼(放在攝像機)移植到安卓才能有效果

using UnityEngine;

using System.Collections;
using System.IO;
using UnityEngine.UI;
public class FingerController : MonoBehaviour
{
    public Transform target;

    private float distance = 0f;
    private float _camerafov;
    private float xSpeed = 40f;
    private float ySpeed = 30f;

    private float yMinLimit = -90;
    private float yMaxLimit = 80;

    private float x = 0.0f;
    private float y = 0.0f;
    private float _lerpspeed = 5f;

    private Vector2 oldPosition1 = new Vector2(0, 0);
    private Vector2 oldPosition2 = new Vector2(0, 0);


    public Text txt;
    public bool isTouchJoystick;
    public bool CanRotate;


    private int fingerId = -1;  //觸控序號
    private Transform m_ptf;

    void Start()
    {
        isTouchJoystick = false;
        CanRotate = false;
        // Debug.Log(oldPosition1);  
        Vector3 angles = transform.eulerAngles;
        x = angles.y;
        y = angles.x;
        _camerafov = Camera.main.fieldOfView;

        m_ptf = GameObject.FindGameObjectWithTag("Player").transform;
    }
    private void OnEnable()
    {
        //EasyJoystick.On_JoystickMoveEnd += OnJoystickMoveEnd; 不用這個用TOuchUp
        EasyJoystick.On_JoystickTouchUp += OnJoystickTouchUp;
    }

    void OnJoystickTouchUp(MovingJoystick move)
    {
        if (move.joystickName != "My joystick")       //  在這裡的名字new joystick 就是上面所說的很重要的名字,在上面圖片中joystickName的你修改了什麼名字,這裡就要寫你修改的好的名字(不然指令碼不起作用)。
        {
            return;
        }
        isTouchJoystick = false;
        //print("移動完成");
    }
    bool TouchIsRight(Vector2 TouchPosition)    //判斷當前觸點是左還是右屏               當然不夠精準
    {
        if (TouchPosition.x >= Screen.width / 2)
        {
            return true;
        }
        else return false;
    }
    void Update()
    {
        // 判斷觸控數量為單點觸控  
        if (Input.touchCount == 1 && !isTouchJoystick)                //單觸,這是情況2,情況1在前一個指令碼實現了
        {
            if (Input.GetTouch(0).phase == TouchPhase.Moved)          
            {
                CanRotate = true;
                x += Input.GetAxis("Mouse X") * xSpeed * Time.deltaTime;
                y -= Input.GetAxis("Mouse Y") * ySpeed * Time.deltaTime;
            }
        }
        else if(Input.touchCount == 2 && isTouchJoystick)             //雙觸,要判斷索引0還是1
        {
            if ( TouchIsRight(Input.GetTouch(1).position)&& Input.GetTouch(1).phase == TouchPhase.Moved)       // 索引 1 是右邊的
            {
                CanRotate = true;
                Vector2 TouchDeltaPosition =  Input.GetTouch(1).deltaPosition;
                x += TouchDeltaPosition.x * xSpeed * Time.deltaTime;
                y -= TouchDeltaPosition.y * ySpeed * Time.deltaTime;
            }
            else if (TouchIsRight(Input.GetTouch(0).position) && Input.GetTouch(0).phase == TouchPhase.Moved)  // 索引 0 是右邊的
            {
                CanRotate = true;
                Vector2 TouchDeltaPosition = Input.GetTouch(0).deltaPosition;
                x += TouchDeltaPosition.x * xSpeed * Time.deltaTime;
                y -= TouchDeltaPosition.y * ySpeed * Time.deltaTime;
            }
        }
        else CanRotate = false;
    }

    void LateUpdate() 
    {
        if (target && CanRotate)                                       //可以旋轉
        {
            y = ClampAngle(y, yMinLimit, yMaxLimit);
            Quaternion rotation = Quaternion.Euler(y, x, 0);

            // 插值運算
            transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * _lerpspeed);
            //m_ptf.eulerAngles = new Vector3(0,y,0);
            Vector3 camrot = transform.eulerAngles;
            camrot.x = 0;camrot.z = 0;
            print(camrot);
            m_ptf.eulerAngles = camrot;         //保證主角和攝像機同步
        }

    }

    static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -90)
            angle = -90;
        if (angle > 80)
            angle = 80;
        return Mathf.Clamp(angle, min, max);
    }
}

Easytouch3.1.6連結:
連結:https://pan.baidu.com/s/16U90JI3hfZ_GaCK5x15FSQ
提取碼:3a2o