C# 如何使用Unity3D中的参数更新Tweener?
我想通过DoTween的DOMoveY快捷方式在2D敌方宇宙飞船的某个部分上下移动。到目前为止一切都很好-它几乎可以工作。。。但是当我在游戏中尝试更改transitionTarget的值时,动画并没有相应地改变 所以问题似乎是代码没有更新Tweener。现在我想知道在游戏过程中,当我更改transitionTarget的值(通过inspector)时,我必须对代码进行哪些更改,以使Tweener得到更新 代码如下:C# 如何使用Unity3D中的参数更新Tweener?,c#,unity3d,animation,game-development,dotween,C#,Unity3d,Animation,Game Development,Dotween,我想通过DoTween的DOMoveY快捷方式在2D敌方宇宙飞船的某个部分上下移动。到目前为止一切都很好-它几乎可以工作。。。但是当我在游戏中尝试更改transitionTarget的值时,动画并没有相应地改变 所以问题似乎是代码没有更新Tweener。现在我想知道在游戏过程中,当我更改transitionTarget的值(通过inspector)时,我必须对代码进行哪些更改,以使Tweener得到更新 代码如下: public float transitionTarget = 0f; pri
public float transitionTarget = 0f;
private Tweener transitionTweener;
private bool toggleTransition = true;
void Start()
{
TransitionTween(transitionTarget);
transitionTweener.OnRewind(() => {
Debug.Log("<<- Transition played backward and completed!");
toggleTransition = true;
});
transitionTweener.OnComplete(() => {
Debug.Log("->> Transition played and completed!");
if (toggleTransition) toggleTransition = false;
else toggleTransition = true;
});
}
void TransitionTween(float targetY) {
transitionTweener = this.transform.DOMoveY(targetY, 3f, false)
.SetEase(Ease.Linear)
.SetAutoKill(false)
.SetId("tran")
.Pause();
}
void Update() {
if (toggleTransition) {
transitionTweener.PlayForward();
}
else {
transitionTweener.PlayBackwards();
}
}
public float transitionTarget=0f;
私人Tweener TransitionWeener;
private bool toggleTransition=true;
void Start()
{
TransitionWeen(transitionTarget);
TransitionWeener.OnRewind(()=>{
Log(“>已播放并完成转换!”);
如果(toggleTransition)toggleTransition=false;
else-toggleTransition=true;
});
}
void transitionween(浮动目标){
TransitionWeener=this.transform.DOMoveY(targetY,3f,false)
.SetEase(Ease.Linear)
.SetAutoKill(错误)
.SetId(“tran”)
.暂停();
}
无效更新(){
如果(切换转换){
transitionWeener.PlayForward();
}
否则{
transitionWeener.PlayBackwards();
}
}
解决方案1:
假设更新后的transitionTarget
在动画周期开始时生效就足够了,那么您的问题有一个简单的解决方案
使用ChangeEndValue
方法
此外,我建议简化:
我建议您使用
SetLoops(-1, LoopType.Yoyo)
通过使用OnStepCompleted
回调可以实现相同的控制量
public class EnemySpaceship : MonoBehaviour {
private Tweener transitionTweener;
public float transitionTarget = 0f;
private Vector3 Endvalue => new Vector3(0.0f, transitionTarget, 0.0f);
void Start()
{
transitionTweener = transform.DOMove(Endvalue, 3f, false)
.SetOptions(AxisConstraint.Y)
.SetEase(Ease.Linear)
.SetLoops(-1, LoopType.Yoyo)
.SetAutoKill(false);
transitionTweener.OnStepComplete(OnStepCompleted);
}
private void OnStepCompleted() {
if (transitionTweener.CompletedLoops() % 2 == 0) {
Debug.Log("->> Transition played and completed!");
transitionTweener.ChangeEndValue(Endvalue);
} else {
Debug.Log("<<- Transition played backward and completed!");
}
}
}
注意:
为了符合您的规范,即当检查器中的transitionTarget
发生更改时,tween应该更新,解决方案将lastValue
与更新方法中的每个帧进行比较。
要在实际应用程序中避免这种情况,您可能需要执行以下操作:
- 将update方法重命名为类似于
,以便手动触发它UpdateTarget
- 使用属性封装
,并使用属性设置器调用transitionTarget
UpdateTarget
- 当tween完成时,另外调用
:UpdateTarget
TransitionWeener.OnComplete(restartween)代码>
transitionTarget
变化时,重新创建二者。
一个比IARI更简单的解决方案(但效率可能更低)是在需要转换时杀死当前的tween,并创建一个具有新目标的新tween。TransitionWeen仅在开始时调用,因此它将转换到分配的第一个transitionTarget,当您更改目标时,您如何触发此操作?或者问题是,您在开始之前在编辑器上设置了一个新值,并且编辑器也会这样做,与目标值无关?您如何准确地更改
切换转换
的值?也不确定是否应该在每一帧调用这些方法。。也许你应该在更改切换时只给他们打一次电话?或者,一旦开始播放,你就不能再通过这些方法改变方向,而是要改变的值。isBackwards
?我想我必须改变的一件事是将“SetAutoKill”改为“true”,因为每次通过编辑器更改“transitionTarget”时,我都需要一个新的Tweener。我将在OnComplete中删除'toggleTransition=true',因为我不需要它。非常感谢您的回答!:)我会尽快查出来的…@drpelz你有机会查出来吗?;)
public class EnemySpaceship : MonoBehaviour {
private Tweener transitionTweener;
public float transitionTarget = 0f;
private float lastValue;
private Vector3 startValue;
private Vector3 Endvalue => new Vector3(0.0f, transitionTarget, 0.0f);
private const float duration = 3f;
void Start() {
lastValue = transitionTarget;
startValue = transform.position;
transitionTweener = transform.DOMove(Endvalue, duration)
.SetOptions(AxisConstraint.Y)
.SetEase(Ease.Linear)
.SetLoops(2, LoopType.Yoyo)
.SetAutoKill(false);
transitionTweener.OnComplete(RestartTween);
}
private void RestartTween() {
transitionTweener.ChangeEndValue(Endvalue);
transitionTweener.Restart();
}
private void Update() {
if (lastValue != transitionTarget && transitionTweener.CompletedLoops() == 0) {
var t = duration * (transform.position.y - startValue.y) / (transitionTarget - startValue.y);
if (t > duration) {
transitionTweener.Goto(2 * duration - transitionTweener.position, true);
} else {
transitionTweener.ChangeEndValue(Endvalue);
transitionTweener.Goto(t, true);
}
lastValue = transitionTarget;
}
}
}