一、基本组件装配
主要思路:把ScrollRrect改造成ScrollCircle ,只要允许水平和垂直都可滑动就行
1.大圆是滑动范围,小圆是手柄。小圆是大圆的子物体。
2.大圆组件挂一个脚本,继承ScrollRect,设置一个滑动半径,允许水平和垂直滑动。
滑动半径R:可以直接用大圆的半径 也可超出或者小于一点点
API里这么写的:If the anchors are together, sizeDelta is the same as size.
锚点四个雪花在一起,sizeDelta就是矩形的长宽 想了解锚点重心矩形组件可以看详细见 Anchor Pivot RectTransform的关系
这里用大圆的边长的三分之一 因为用大圆半径滑的手累
层级版面里,小圆扔到大圆的content里。
4.小圆的锚点固定在大圆中心,小圆以锚点为原点,滑动的距离不可以超过滑动半径。
小圆滑动的距离=AchoredPostion.magnitude//向量长度
二、摇杆块的滑动和复位功能
☆☆☆☆☆最重要的知识点:AchoredPostion
变量AchoredPostion:是锚点到重心点的向量 既有方向又有大小
可以获取小圆基于锚点的滑动向量(一)滑动时AchoredPostion的作用
大小超出滑动半径R, 不允许继续往外滑动 ,但是滑动方向要保留,要将小圆限制在大圆边缘
控制的人物可以继续移动 ,方向可以改变
if(滑动向量长度>可滑动范围半径)
content.anchoredPosition = content.anchoredPosition.normalized * r;
向量单位化 变成(1,1),保留滑动向量的方向 ,(1,1)*R,滑动向量的长度置为滑动半径,这样就将小圆限制在大圆边缘
(二)不滑动时AchoredPostion的作用——复位将摇杆复位 小圆偏离锚点的向量为0
content.anchoredPosition = new Vector2(0, 0);//复位 小圆回到锚点
三、控制物体移动
1.物体移动的加速度 这里偷个懒
用摇杆移动的向量长度控制移动速度 也就是说摇杆偏离锚点越远 物体速度越快
speed = content.anchoredPosition.magnitude/5;2.把摇杆的移动向量单位化只保留移动方向 再乘以移动速度
四、代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
/// <summary>
/// AchoredPostion是锚点到重心点的向量 既有方向又有大小
/// </summary>
public class Handler : ScrollRect{
public float speed = 10;
private float r;//滑动半径
private float mr;//小圆正在滑动的半径
private bool isOnDrag;
public GameObject p;
void Start () {
//RectTransform继承了transform,脚本只能调用transform,这里强制转换
r = (transform as RectTransform).sizeDelta.x /3;//设置滑动半径 这里用大圆半径的1/3
horizontal = true;
vertical = true;
p = GameObject.FindGameObjectWithTag("Player");
}
private void Update()
{
Vector2 V = content.anchoredPosition; //获取滑动向量
controllPlayer(V);//控制移动
}
//小球滑动功能
public override void OnDrag(PointerEventData eventData)
{
base.OnDrag(eventData);
isOnDrag = true;
mr = content.anchoredPosition.magnitude;//小圆滑动向量的长度
Debug.Log("允许的半径:"+r+" 已滑动的半径:"+mr);
if(mr > r){
Debug.Log("超出范围");
//接下来控制小球在边缘不出去 也就是说anchoredpostion的长度要=r 但是人物移动方向还是要存在 所以利用滑动向量单位化 仅保留方向 长度置为1
content.anchoredPosition = content.anchoredPosition.normalized * r;//向量单位化 保留方向变化 向量长度为1*R
//Wrong content.anchoredPosition = new Vector2(r, r);//错误的做法 因为丢失了方向
}
}
//小球复位功能 当玩家松手之后 小球才能复位
public override void OnEndDrag(PointerEventData eventData)
{
base.OnEndDrag(eventData);
Debug.Log("-----------------------------------------Stopped dragging!");
content.anchoredPosition = new Vector2(0, 0);//复位
isOnDrag = false;
}
//控制移动
private void controllPlayer(Vector2 v)//传入摇杆的滑动向量
{
float x = v.x;//获取x轴的向量 有长度+方向
float y = v.y;//y轴的
if (isOnDrag == true)
speed = content.anchoredPosition.magnitude/5;//设置速度=向量长度的五分之一
p.transform.Translate(new Vector3(x, y, 0).normalized * Time.deltaTime * speed);//仅保留方向的单位向量 乘以 速度
}
}