Unity学习笔记—轮转图

轮转图是指在一个模块或者窗口,通过鼠标点击或滑动后,可以看到多张图片或模型之间不断切换,如何实现轮转图:

先计算每个要显示的图片或模型的位置,在对应位置生成物体:

public GameObject obj;
public int num;
public int r;
float ang_all = 0;
List<GameObject> list = new List<GameObject>();
List<Transform> pos = new List<Transform>();
float angle;
float dec = 1;
private void Start()
{
    angle = 2 * Mathf.PI / num;
    for (int i = 0; i < num; i++)
    {
        float x = Mathf.Sin(i * angle) * r;
        float z = Mathf.Cos(i * angle) * r;
        GameObject go = Instantiate(obj);
        go.transform.parent = transform;
        go.transform.localPosition = new Vector3(x, 0, z);
        go.GetComponent<RoleItem>().cyclogram = this;
        list.Add(go);
        pos.Add(go.transform);
    }
}

然后给物体挂载一个脚本,用来监听拖拽行为:

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

public class RoleItem : MonoBehaviour
{
    public Cyclogram cyclogram;
    private void OnMouseDrag()
    {
        Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
        Vector3 next = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, pos.z));
        float dis = transform.position.x - next.x;
        cyclogram.OnDrag(dis);
    }
    private void OnMouseUp()
    {
        Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
        Vector3 next = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, pos.z));
        float dis = transform.position.x - next.x;
        cyclogram.Inertia(dis);
    }
}

计算鼠标拖拽产生和物体位置的差值发送给轮转图脚本里的OnDrag函数,控制所有物体同步进行旋转:

public void OnDrag(float dis)
{
    float ang_move = dis / r;
    ang_all += ang_move;
    for (int i = 0; i < list.Count; i++)
    {
        float x = Mathf.Sin(i * angle + ang_all) * r;
        float z = Mathf.Cos(i * angle + ang_all) * r;
        list[i].transform.localPosition = new Vector3(x, 0, z);
    }
}

这样简单的轮转图就做好了,现在的轮转图物体旋转后停止会非常突兀,接下来制作物体旋转时的惯性效果:

public class MyDoTween : MonoBehaviour
{
    public Action<float> action;
    public Action complete;
    public float start;
    public float end;
    public float time;
    float nowTime;
    public static MyDoTween To(Action<float> action, float start, float end, float time)
    {
        GameObject go = new GameObject("DT");
        MyDoTween dt = go.AddComponent<MyDoTween>();
        dt.action = action;
        dt.start = start;
        dt.end = end;
        dt.time = time;
        dt.nowTime = Time.time;
        return dt;
    }
    private void Update()
    {
        if (Time.time - nowTime < time)
        {
            float t = Time.time - nowTime;
            float p = t / time;
            float a = start * (1 - p) + end * p;
            action(a);
        }
        else
        {
            action(end);
            complete?.Invoke();
            Destroy(gameObject);
        }
    }
    public void OnComplete(Action complete)
    {
        this.complete = complete;
    }
}

上图仿照DoTween的To方法实现了一个简单的随时间变化返回差值的脚本,使用这个脚本完成物体惯性以及自动对齐的效果:

public void Inertia(float dis)
{
    MyDoTween.To((a) =>
    {
        OnDrag(a);
    }, dis, 0, Mathf.Abs(dis / dec)).OnComplete(() =>
    {
        pos.Sort((a, b) => (int)(a.localPosition.z - b.localPosition.z));
        float aligning = Mathf.Asin(pos[0].localPosition.x / r);
        float aligningtime = Mathf.Abs(aligning * r / dec);
        MyDoTween.To((a) =>
        {
            ang_all = a;
            for (int i = 0; i < list.Count; i++)
            {
                float x = Mathf.Sin(i * angle + ang_all) * r;
                float z = Mathf.Cos(i * angle + ang_all) * r;
                list[i].transform.localPosition = new Vector3(x, 0, z);
            }
        }, ang_all, ang_all + aligning, aligningtime);
    });
}

最终实现的效果:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值