【Unity 27】 Unity中的 UI部分接口,简易震荡效果,模拟摇杆操作,小地图显示

PS:本系列笔记将会记录我此次在北京学习Unity开发的总体过程,方便后期写总结,笔记为日更。
笔记内容均为 自己理解,不保证每个都对

实现 简易模拟摇杆控制物体旋转,移动,小地图光标的同步移动与旋转

Part 1 UI部分接口:

使用UI接口时,要引用 EventSystems的库文件

using UnityEngine.EventSystems;

该博客举例部分接口为:

    IPointerClickHandler, IPointerDownHandler, IPointerEnterHandler, IPointerExitHandler, IPointerUpHandler,
    IDragHandler,IBeginDragHandler

使用方法:

public class UIInterfaceTest : MonoBehaviour,
    IPointerClickHandler, IPointerDownHandler, IPointerEnterHandler, IPointerExitHandler, IPointerUpHandler,
    IDragHandler,IBeginDragHandler
{
    public void OnBeginDrag(PointerEventData eventData)     //鼠标按下开始拖动
    {
        Debug.Log("OnBeginDrag !!!");
    }

    public void OnDrag(PointerEventData eventData)      //正在拖动
    {
        transform.position = eventData.position;        //拖动图片
        Debug.Log("OnDrag !!!");
    }


    public void OnEndDrag(PointerEventData eventData)       //结束拖动
    {
        Debug.Log("OnEndDrag !!!");
    }

    public void OnPointerClick(PointerEventData eventData)      //鼠标按下松开
    {
        Debug.Log("OnPointerClick !!!");
    }

    public void OnPointerDown(PointerEventData eventData)       //鼠标按下不松开
    {
        Debug.Log("OnPointerDown !!!");
    }

    public void OnPointerEnter(PointerEventData eventData)      //鼠标进入
    {
        Debug.Log("OnPointerEnter !!!");
    }

    public void OnPointerExit(PointerEventData eventData)       //鼠标离开
    {
        Debug.Log("OnPointerExit !!!");
    }

    public void OnPointerUp(PointerEventData eventData)     //鼠标松开
    {
        Debug.Log("OnPointerUp !!!");
    }

显示输出结果为:
【Unity 27】 Unity中的 UI部分接口,简易震荡效果,模拟摇杆操作,小地图显示_第1张图片
可完成鼠标拖动物体DEMO: 脚本挂在物体上

    public void OnDrag(PointerEventData eventData)      //正在拖动
    {
        transform.position = eventData.position;        //拖动图片
        Debug.Log("OnDrag !!!");
    }

Part 2 简易震荡效果:

利用Sin三角函数进行模拟:实现血条减少的时候会在 减少值区间小幅度震荡

public class DeHp : MonoBehaviour
{

    Image tmpImg;
    float orinHp, changeHp, angle;
    //orinHp 初始值
    //changeHp 震荡范围
    //angle 震荡角度
    // Start is called before the first frame update
    void Start()
    {
        tmpImg = gameObject.GetComponent();      //获得Image组件
        orinHp = tmpImg.fillAmount;     //获得血量图片的初始值

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))        //空格键按下时触发
        {
            Debug.Log("KeyCode.Space   !!!");
            orinHp = tmpImg.fillAmount - 0.05f;     //血量减少的0.05f

            angle = 0;
            changeHp = 0.3f;
        }

        if(changeHp >= 0)
        {
            angle += Time.deltaTime * 30;        //修改震荡角度,趋于90°

            changeHp -= Time.deltaTime;     //修改震荡幅度,   震荡角和震荡幅度逐渐趋于平缓

            tmpImg.fillAmount = orinHp + tmpImg.fillAmount * Time.deltaTime * Mathf.Sin(angle);

        }

    }
}

Part 3 模拟摇杆操作 :

主要实现:
1、在摇杆圆内任意移动
2、超过摇杆圆的半径时,操作盘位于圆的交点
3、鼠标按下时,操作盘放大
4、鼠标松开时,操作盘归位
5、物体随着摇杆移动旋转方向
5、控制物体移动

代码实现:

1、2、3、4 操作盘 代码实现:


    public Transform target;       //获得摇杆位置
    public Transform player;       //获得玩家位置
    public Transform playerArrow;      //记录玩家光标的位置
    public Transform terrian;      //获得Terrian信息
    public Transform Map;     //获得MiniMap信息

    float Radius = 0;       //获得底部半径
    Vector2 center;     //记录圆心坐标
    bool isHold = false;        //记录是否在拖拽



    public void OnBeginDrag(PointerEventData eventData)		//鼠标按下,操作盘放大
    {
        target.localScale = new Vector3(1.1f, 1.1f, 1.1f);       //选中时放大
    }



    public void OnDrag(PointerEventData eventData)      //拖拽时跟随鼠标移动
    {
        isHold = true;      //拖拽标记 记为true

        float tmpDistance = Vector3.Distance(transform.position, eventData.position);       //计算圆心到鼠标位置的距离

        Vector2 tmpVector = eventData.position - center;        //获得圆心到鼠标点的向量

        if(tmpDistance <= Radius)       //距离小于等于底部圆的半径
        {
            target.position = eventData.position;
        }
        else
        {
            target.position = center + tmpVector.normalized * Radius;        //圆心加上 单位向量 * 半径   即为圆心到鼠标点 连线与圆的交点,即为摇杆的位置
        }
     }


    public void OnEndDrag(PointerEventData eventData)			//鼠标松开,操作盘归位
    {
        isHold = false;     //拖拽标记记为false
        target.localScale = new Vector3(1, 1, 1);       //松开时恢复原大小
        target.position = transform.position;
    }




    void Start()
    {
        Debug.Log("transform.position == " + transform.position);
        center = transform.position;        //获得圆心坐标
        Debug.Log("center == " + center);
        RectTransform tmpRect = transform.GetComponent();        //获得 Rect Transform组件
        Radius = tmpRect.sizeDelta.x / 2;       //因为底部是圆形,所以半径是 x 轴的一半
    }

5 控制旋转:
添加在 public void OnDrag(PointerEventData eventData)方法中

        float rad = Mathf.Atan2(tmpVector.y, tmpVector.x);        //反三角求出夹角
        float angle = Mathf.Rad2Deg * rad;      //求夹角
        Vector3 tmpEuler = player.localEulerAngles;     //获得原物体的欧拉角
        tmpEuler.y = 90 - angle;            //绕着Y轴旋转

        player.transform.localEulerAngles = tmpEuler;       //将修改后的欧拉 赋给物体

6控制移动:
添加在Update方法中, isHold就是用来标记摇杆是否正在拖动

        if(isHold == true)      //拖拽中
        {
            player.transform.Translate(Vector3.forward, Space.Self);      //向自身坐标的Y轴移动一个单位  
            }

Part 4 小地图显示:

主要实现:
1、小地图光标随着物体移动而移动
2、物体旋转时,光标也发生相应的旋转

主要方式思路:
1、光标移动,利用 原物体在大地图中的 坐标比例 可求小地图坐标
2、光标旋转,与摇杆控制物体旋转一样

光标移动:

    void Update()
    {
        if(isHold == true)      //拖拽中
        {
            player.transform.Translate(Vector3.forward, Space.Self);      //向自身坐标的Y轴移动一个单位  



            Vector3 TerrianSize = terrian.GetComponent().terrainData.size;     //获得terrian的 大小信息



            Vector3 tmpDis = player.position - terrian.position;

            float rateX = tmpDis.x / TerrianSize.x - 0.5f;      //计算X轴比例
            float rateZ = tmpDis.z / TerrianSize.z - 0.5f;      //计算Y轴比例

            RectTransform MapSize = Map.GetComponent();      //获得RectTransform组件

            float newX = MapSize.sizeDelta.x * rateX;       //根据比例计算箭头在小地图中的X轴坐标
            float newY = MapSize.sizeDelta.y * rateZ;       //根据比例计算箭头在小地图中的Y轴坐标


            playerArrow.position = new Vector3(MapSize.position.x + newX, MapSize.position.y + newY);       

            //Debug.Log("playerArrow.position == " + playerArrow.position);


        }
    }

光标旋转:
添加在public void OnDrag(PointerEventData eventData)方法中

        tmpEuler = playerArrow.localEulerAngles;        //获得原箭头的欧拉
        tmpEuler.z = angle;     //绕着Z轴旋转
        playerArrow.transform.localEulerAngles = tmpEuler;      //将修改后的欧拉赋给物体

总体代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class JoyMove : MonoBehaviour, IDragHandler, IEndDragHandler, IBeginDragHandler
{
    public Transform target;       //获得摇杆位置
    public Transform player;       //获得玩家位置
    public Transform playerArrow;      //记录玩家光标的位置
    public Transform terrian;      //获得Terrian信息
    public Transform Map;     //获得MiniMap信息

    float Radius = 0;       //获得底部半径
    Vector2 center;     //记录圆心坐标
    bool isHold = false;        //记录是否在拖拽

    public void OnBeginDrag(PointerEventData eventData)
    {
        target.localScale = new Vector3(1.1f, 1.1f, 1.1f);       //选中时放大
    }

    public void OnDrag(PointerEventData eventData)      //拖拽时跟随鼠标移动
    {
        isHold = true;      //拖拽标记 记为true

        float tmpDistance = Vector3.Distance(transform.position, eventData.position);       //计算圆心到鼠标位置的距离

        Vector2 tmpVector = eventData.position - center;        //获得圆心到鼠标点的向量

        if(tmpDistance <= Radius)       //距离小于等于底部圆的半径
        {
            target.position = eventData.position;
        }
        else
        {
            target.position = center + tmpVector.normalized * Radius;        //圆心加上 单位向量 * 半径   即为圆心到鼠标点 连线与圆的交点,即为摇杆的位置
        }


        float rad = Mathf.Atan2(tmpVector.y, tmpVector.x);        //反三角求出夹角
        float angle = Mathf.Rad2Deg * rad;      //求夹角
        Vector3 tmpEuler = player.localEulerAngles;     //获得原物体的欧拉角
        tmpEuler.y = 90 - angle;            //绕着Y轴旋转

        player.transform.localEulerAngles = tmpEuler;       //将修改后的欧拉 赋给物体


        tmpEuler = playerArrow.localEulerAngles;        //获得原箭头的欧拉
        tmpEuler.z = angle;     //绕着Z轴旋转
        playerArrow.transform.localEulerAngles = tmpEuler;      //将修改后的欧拉赋给物体
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        isHold = false;     //拖拽标记记为false
        target.localScale = new Vector3(1, 1, 1);       //松开时恢复原大小
        target.position = transform.position;
    }

    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("transform.position == " + transform.position);
        center = transform.position;        //获得圆心坐标
        Debug.Log("center == " + center);
        RectTransform tmpRect = transform.GetComponent();        //获得 Rect Transform组件
        Radius = tmpRect.sizeDelta.x / 2;       //因为底部是圆形,所以半径是 x 轴的一半
    }

    // Update is called once per frame
    void Update()
    {
        if(isHold == true)      //拖拽中
        {
            player.transform.Translate(Vector3.forward, Space.Self);      //向自身坐标的Y轴移动一个单位  



            Vector3 TerrianSize = terrian.GetComponent().terrainData.size;     //获得terrian的 大小信息



            Vector3 tmpDis = player.position - terrian.position;

            float rateX = tmpDis.x / TerrianSize.x - 0.5f;      //计算X轴比例
            float rateZ = tmpDis.z / TerrianSize.z - 0.5f;      //计算Y轴比例

            RectTransform MapSize = Map.GetComponent();      //获得RectTransform组件

            float newX = MapSize.sizeDelta.x * rateX;       //根据比例计算箭头在小地图中的X轴坐标
            float newY = MapSize.sizeDelta.y * rateZ;       //根据比例计算箭头在小地图中的Y轴坐标


            playerArrow.position = new Vector3(MapSize.position.x + newX, MapSize.position.y + newY);       

            //Debug.Log("playerArrow.position == " + playerArrow.position);


        }
    }
}

最终效果:
【Unity 27】 Unity中的 UI部分接口,简易震荡效果,模拟摇杆操作,小地图显示_第2张图片

你可能感兴趣的:(Unity)