目標(biāo):實(shí)現(xiàn)類似拖拽后“飄回”原位的效果
我們知道改變物體的位置可以通過對transform.position
賦值實(shí)現(xiàn),但這是一次性的贾惦,哪怕使用了Lerp
將一段距離均分為100份放在Update
函數(shù)中敞峭,也是在當(dāng)前的一幀內(nèi)穗酥,直接“閃現(xiàn)”到目標(biāo)位置
其實(shí)是因?yàn)橛鞍撸魧⑺写a均放于Update
,那么這一百份更新初婆,仍舊會在這一幀的時(shí)間內(nèi)執(zhí)行完蓬坡,而并非均分到各幀
而對于拖拽事件,則相當(dāng)于每一幀獲取鼠標(biāo)的世界坐標(biāo)磅叛,并賦值給物體即可
知道了這些屑咳,就可以寫下如下代碼實(shí)現(xiàn)功能,基本變量與函數(shù)功能均已注釋:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
// 復(fù)位時(shí)間(速度)
float duration = 0.5f, currentTime = 0f;
bool isDrag = false;
// 初始位置坐標(biāo)宪躯,復(fù)位時(shí)每次的偏移
Vector3 originPos, offset;
// 物體的屏幕坐標(biāo)
Vector3 screenSpace;
void Start()
{
originPos = transform.position;
}
void Update()
{
// 鼠標(biāo)按下乔宿,拖拽事件
if(Input.GetMouseButtonDown(0))
{
// 物體世界坐標(biāo)轉(zhuǎn)為屏幕坐標(biāo)
screenSpace = Camera.main.WorldToScreenPoint(transform.position);
isDrag = true;
}
// 鼠標(biāo)松開,返回原位
else if(Input.GetMouseButtonUp(0))
{
isDrag = false;
offset = originPos - transform.position;
}
if(!isDrag && transform.position != originPos)
{
ResetPosition();
}
// 鼠標(biāo)一直按下未松開访雪,執(zhí)行拖拽
if (isDrag)
{
DragObject();
}
}
// 復(fù)位
private void ResetPosition()
{
// 每次向offset的方向偏移
if (currentTime < duration)
{
transform.position += offset * Time.deltaTime / duration;
currentTime += Time.deltaTime;
}
// 若移動足夠的時(shí)間详瑞,賦值最終位置,重置當(dāng)前移動時(shí)間
else
{
transform.position = originPos;
currentTime = 0;
}
}
// 拖拽
private void DragObject()
{
Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);
var curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace);
transform.position = curPosition;
}
}