Unity动画与UI操作技巧记录
使用DOTween实现复杂动画序列
通过DOTween库可构建多步骤动画流程,支持旋转、位移、缩放、摄像机视角调整等复合效果。
function playComplexAnimation()
local startPostion = go.transform.position
local sequence = DG.Tweening.DOTween.Sequence()
-- 1. 旋转360度(快速绕过360)
sequence:Append(go.transform:DORotate(Vector3(0, 0, 360), 1, DG.Tweening.RotateMode.FastBeyond360))
-- 2. 摇晃位置
sequence:Join(go.transform:DOShakePosition(2, Vector3.New(2, 2, 3)))
-- 3. 跳跃移动至目标点
sequence:Append(go.transform:DOJump(Vector3.New(startPostion.x + 100, startPostion.y, startPostion.z), 5, 3, 3))
-- 4. 多段线性位移,不同缓动函数
sequence:Append(go.transform:DOMove(Vector3.New(20, 20, 30), 2)):SetEase(DG.Tweening.Ease.Linear)
sequence:Append(go.transform:DOMove(Vector3.New(70, 80, 30), 2)):SetEase(DG.Tweening.Ease.OutQuad)
sequence:Append(go.transform:DOMove(Vector3.New(120, 120, 30), 2)):SetEase(DG.Tweening.Ease.InOutCubic)
sequence:Append(go.transform:DOMove(Vector3.New(200, 200, 30), 2)):SetEase(DG.Tweening.Ease.InCirc)
-- 5. 沿路径移动(局部坐标路径)
local cityScene = GameObject.FindWithTag("cityScene").transform
local house = cityScene:FindChild("house").gameObject
local pathPoints = {
Vector3.New(17, 10, 5.7),
Vector3.New(1, 10, 0),
Vector3.New(1, 10, 20),
Vector3.New(11, 10, 10)
}
sequence:Append(house.transform:DOLocalPath(pathPoints, 12, DG.Tweening.PathType.Linear, DG.Tweening.PathMode.Full3D, 10, nil))
-- 6. 摄像机转向目标点
sequence:Append(self.worldCamera.transform:DOLookAt(Vector3.New(0, 1, 0), 20, DG.Tweening.AxisConstraint.Y))
-- 7. 执行并设置完成回调
sequence:Play()
sequence:OnComplete(function()
logWarn("动画全部执行完毕")
end)
end
动态修改RectTransform布局参数
直接通过脚本控制UI元素的锚点、偏移量和尺寸,适用于动态布局或交互反馈。
function updateRectTransform()
local rectTransform = targetObject:GetComponent('RectTransform')
-- 改变顶部边界
rectTransform.offsetMax = Vector2.New(0, 0)
-- 改变底部边界
rectTransform.offsetMin = Vector2.New(0, 0)
-- 修改宽高
rectTransform.sizeDelta = Vector2.New(200, 100)
-- 设置位置(2D/3D)
rectTransform.anchoredPosition = Vector2.New(50, 30)
rectTransform.anchoredPosition3D = Vector3.New(50, 30, 0)
end
嵌套动画与回调控制
在动画链中插入子动画,并在主序列完成后触发后续行为。
function setupNestedAnimation()
local startY = VectorPos.y
local tweener = go.transform:DOMoveY(startY, 3):SetEase(DG.Tweening.Ease.InOutSine)
local function onCompleteCallback()
logWarn("Y轴移动完成")
tweener:Pause()
go.transform:DOScale(3, 1)
go.transform:DOMoveY(0, 1.5):SetEase(DG.Tweening.Ease.OutBounce)
end
local sequence = DG.Tweening.DOTween.Sequence()
sequence:Append(go.transform:DOMoveX(VectorPos.x + 75, 1.5):SetEase(DG.Tweening.Ease.OutSine))
sequence:Append(go.transform:DOMoveX(VectorPos.x - 75, 1.5):SetEase(DG.Tweening.Ease.InSine))
sequence:Play()
sequence:OnComplete(onCompleteCallback)
end
基于射线检测的物体移动与寻路
结合物理射线检测与A*算法实现可交互建筑移动逻辑。
function testMove(pos)
if self.testAstae then
local ray = self.componentCamera:ScreenPointToRay(pos)
local layerMask = 2 ^ LayerMask.NameToLayer('TerrainLayer')
local hit, result = UnityEngine.Physics.Raycast(ray, nil, 5000, layerMask)
if hit then
local touchPoint = result.point
local originalPos = self.testAstae.transform.position
self.testAstae.transform.position = touchPoint
local localTouch = self.testAstae.transform.localPosition
-- 回退原位置
self.testAstae.transform.position = originalPos
-- 遍历可放置区域判断是否命中
for i = 1, #self.touchPaceTable do
local info = self.touchPaceTable[i]
local contains, targetPos = self:Contains(localTouch, info["pos"])
if contains then
if self.toolAstar then
local from = Vector3.New(localTouch.x, localTouch.z, 0)
local to = Vector3.New(targetPos.x, targetPos.z, 0)
self.toolAstar:moveToward(from, to)
end
break
end
end
end
end
end
路径动画配置选项
使用DOPath创建平滑路径动画,并可自定义行为选项。
Vector3[] path = new Vector3[] {
new Vector3(1, 2, 2),
new Vector3(8, 0, 4),
new Vector3(9, 2, 14),
new Vector3(5, 4, 10),
new Vector3(2, 4, 4)
};
// 使用CatmullRom生成平滑曲线路径
Tweener tween = target.DOPath(path, 2.0f, PathType.CatmullRom);
// 可选:自动返回起点
tween.SetOptions(true);
// 可选:仅限制某轴运动(如仅允许Z轴变化)
tween.SetOptions(true, AxisConstraint.Y);
// 可选:让对象始终朝向路径前进方向
tween.SetLookAt(target.transform.position);