Unity3D,请问如何给一个动画事件调用的函数传参数?

templar616 2014-09-28 07:21:58
现在有一个AttTar(Action CurAct)函数,该函数由一个攻击动作的动画在播放到第50帧的时候调用

Action是一个struct
public struct Action
{
public Transform Att;
public Transform Def;
public INI_SKI Ski;
}

已经准备好了一个Action NewAct

请问如何把NewAct传给函数AttTar(Action CurAct)的参数CurAct,以便动画在播放到第50帧的时,调用AttTar函数能获取到这个NewAct?

在线跪求,还望各位路过的大神不吝赐教……Orz


(请给个最简单的示例)
...全文
7330 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
killua_z 2015-08-25
  • 打赏
  • 举报
回复
写个不带参数的AttTar,调用带参数的AttTar。。
lm3478 2015-01-30
  • 打赏
  • 举报
回复
个人觉得,这个设计貌似不太科学。。。 攻击动画播到50帧,只需要发布1个事件出去,让关注这个事件的对象调用 函数AttTar就行了。。。至于你说的参数。。事件都有了,参数还不是你说了算?
  • 打赏
  • 举报
回复
既然能手动托,肯定能代码写!只不过没有找到而已! 你可以把这个动画切成两部分,两个动画连续播放,再播放第二个动画之前插入一个事件就可以了! 如果要求不高的话,可以按时间算!
templar616 2014-09-30
  • 打赏
  • 举报
回复
引用 24 楼 F_blacksorrow 的回复:
Action是一个struct,不建议在C#用struct... 请把Action这样写 public class Action { privateTransform Att; privateTransform Def; private INI_SKI Ski; public Action(Transform atk,Transform def,INI_SKI ski) { Att = atk; Def = def; Ski = ski; } }
E……这样做也行,但是为什么不建议在C#用struct呢?
templar616 2014-09-29
  • 打赏
  • 举报
回复
引用 17 楼 candycat1992 的回复:
那就靠Trigger

using UnityEngine;
using System.Collections;

public class AnimTriggers : MonoBehaviour
{	
	// Create a reference to the animator component
	private Animator animator;
	
	
	void Start ()
	{
		// initialise the reference to the animator component
		animator = gameObject.GetComponent<Animator>();
	}
	
	// check for colliders with a Trigger collider
	// if we are entering something called JumpTrigger, set a bool parameter called JumpDown to true..
	void OnTriggerEnter(Collider col)
	{
		if(col.gameObject.name == "JumpTrigger")
		{
			animator.SetBool("JumpDown", true);	
		}
	}
	
	// ..and when leaving the trigger, reset it to false
	void OnTriggerExit(Collider col)
	{
		if(col.gameObject.name == "JumpTrigger")
		{
			animator.SetBool("JumpDown", false);
		}
	}
}
你好,我不是太明白这句 void OnTriggerEnter(Collider col) 里传进来的col是什么东西? 另外还想请教一下,这个OnTriggerEnter函数会在什么时候被调用? 目前我知道的OnTriggerEnter是在刚体被碰撞到的时候调用
  • 打赏
  • 举报
回复
那就靠Trigger

using UnityEngine;
using System.Collections;

public class AnimTriggers : MonoBehaviour
{	
	// Create a reference to the animator component
	private Animator animator;
	
	
	void Start ()
	{
		// initialise the reference to the animator component
		animator = gameObject.GetComponent<Animator>();
	}
	
	// check for colliders with a Trigger collider
	// if we are entering something called JumpTrigger, set a bool parameter called JumpDown to true..
	void OnTriggerEnter(Collider col)
	{
		if(col.gameObject.name == "JumpTrigger")
		{
			animator.SetBool("JumpDown", true);	
		}
	}
	
	// ..and when leaving the trigger, reset it to false
	void OnTriggerExit(Collider col)
	{
		if(col.gameObject.name == "JumpTrigger")
		{
			animator.SetBool("JumpDown", false);
		}
	}
}
饭饭000 2014-09-29
  • 打赏
  • 举报
回复
引用 24 楼 F_blacksorrow 的回复:
Action是一个struct,不建议在C#用struct... 请把Action这样写 public class Action { privateTransform Att; privateTransform Def; private INI_SKI Ski; public Action(Transform atk,Transform def,INI_SKI ski) { Att = atk; Def = def; Ski = ski; } }
作为类中类。操作构造函数就行。
饭饭000 2014-09-29
  • 打赏
  • 举报
回复
Action是一个struct,不建议在C#用struct... 请把Action这样写 public class Action { privateTransform Att; privateTransform Def; private INI_SKI Ski; public Action(Transform atk,Transform def,INI_SKI ski) { Att = atk; Def = def; Ski = ski; } }
dabojue 2014-09-29
  • 打赏
  • 举报
回复
我也是新手,学习学习
  • 打赏
  • 举报
回复
没关系,分对我不是那么重要。不能换人民币。。。。
templar616 2014-09-29
  • 打赏
  • 举报
回复
不好意思哈,咱就这点分啦
templar616 2014-09-29
  • 打赏
  • 举报
回复
引用 19 楼 candycat1992 的回复:
So sorry,我之前看错了。。。 我查了很久没有查到,我能想到的就是下面这样

		AnimatorStateInfo currentState = animator.GetCurrentAnimatorStateInfo(0);
		if (currentState.nameHash == Animator.StringToHash("Base Layer.Idle"))
		{
			if (!hasSet) {
				Action act = new Action();
				act.Att = this.transform;
				act.Def = this.transform;
				
				AnimationEvent evt = new AnimationEvent();
				evt.time = 0;
				evt.functionName = "Test";
				evt.objectReferenceParameter = act as Object;
				
				AnimationInfo[] info = animator.GetCurrentAnimationClipState(0);

				foreach (AnimationInfo i in info) {
					i.clip.AddEvent(evt);
					hasSet = true;
				}
			}
		}
但是感觉也不好。我觉得你这种动态在代码里设置参数的需求是要得到Animation Clip的吧,但是用新的动画系统这种要求本身就比较麻烦。。。感觉这个系统还有很多API没有开放,不是很灵活。 我尽力了。。。
多谢你耐心的讨论 再等等吧,7天没更好的回复分就给你啦
templar616 2014-09-29
  • 打赏
  • 举报
回复
引用 15 楼 candycat1992 的回复:
你可以动态添加函数和参数,类似下面这样

using UnityEngine;
using System.Collections;

public class Try : MonoBehaviour {

	public class Action : ScriptableObject
	{
		public Transform Att;
		public Transform Def;
	}

	// Use this for initialization
	void Start () {
		Action act = new Action();
		act.Att = this.transform;
		act.Def = this.transform;

		AnimationEvent evt = new AnimationEvent();
		evt.time = 0;
		evt.functionName = "Test";
		evt.objectReferenceParameter = act as Object;
		animation.GetClip("ani").AddEvent(evt);

		Debug.Log(act.Att.gameObject.name);
	}	
	
	public void Test(Action obj) {
		Action act = obj as Action;
		Debug.Log(act.Att.gameObject.name);
	}
}

因为是用的新动画系统……人物已经没有Animation组件了,只有一个Animator组件的
  • 打赏
  • 举报
回复
So sorry,我之前看错了。。。 我查了很久没有查到,我能想到的就是下面这样

		AnimatorStateInfo currentState = animator.GetCurrentAnimatorStateInfo(0);
		if (currentState.nameHash == Animator.StringToHash("Base Layer.Idle"))
		{
			if (!hasSet) {
				Action act = new Action();
				act.Att = this.transform;
				act.Def = this.transform;
				
				AnimationEvent evt = new AnimationEvent();
				evt.time = 0;
				evt.functionName = "Test";
				evt.objectReferenceParameter = act as Object;
				
				AnimationInfo[] info = animator.GetCurrentAnimationClipState(0);

				foreach (AnimationInfo i in info) {
					i.clip.AddEvent(evt);
					hasSet = true;
				}
			}
		}
但是感觉也不好。我觉得你这种动态在代码里设置参数的需求是要得到Animation Clip的吧,但是用新的动画系统这种要求本身就比较麻烦。。。感觉这个系统还有很多API没有开放,不是很灵活。 我尽力了。。。
  • 打赏
  • 举报
回复
你可以动态添加函数和参数,类似下面这样

using UnityEngine;
using System.Collections;

public class Try : MonoBehaviour {

	public class Action : ScriptableObject
	{
		public Transform Att;
		public Transform Def;
	}

	// Use this for initialization
	void Start () {
		Action act = new Action();
		act.Att = this.transform;
		act.Def = this.transform;

		AnimationEvent evt = new AnimationEvent();
		evt.time = 0;
		evt.functionName = "Test";
		evt.objectReferenceParameter = act as Object;
		animation.GetClip("ani").AddEvent(evt);

		Debug.Log(act.Att.gameObject.name);
	}	
	
	public void Test(Action obj) {
		Action act = obj as Action;
		Debug.Log(act.Att.gameObject.name);
	}
}

  • 打赏
  • 举报
回复
为什么。。。我们之前的游戏就是这样子写的。。。
templar616 2014-09-28
  • 打赏
  • 举报
回复
引用 12 楼 candycat1992 的回复:
貌似Unity只支持在runtime的时候添加一个AnimationEvent, http://docs.unity3d.com/ScriptReference/AnimationClip.AddEvent.html 你可以靠event的time来指定什么时候出发。 或者你可以之前用一个更猥琐的方法,就是Coroutine。。。判断动画播放到哪一个时间后出发一个函数,这样就可以随便写了。
这样肯定不符合要求的……
  • 打赏
  • 举报
回复
貌似Unity只支持在runtime的时候添加一个AnimationEvent, http://docs.unity3d.com/ScriptReference/AnimationClip.AddEvent.html 你可以靠event的time来指定什么时候出发。 或者你可以之前用一个更猥琐的方法,就是Coroutine。。。判断动画播放到哪一个时间后出发一个函数,这样就可以随便写了。
蓝色記憶 2014-09-28
  • 打赏
  • 举报
回复
引用 10 楼 templar616 的回复:
[quote=引用 8 楼 hgplan 的回复:] 貌似现在Action调用的函数参数只能够支持一个float,或者一个Transform的情况。更多的参数和更多的参数类型是不支持这样做的吧。你可以把你的参数做成全局的呀,然后把某些具体要改变的数值写在函数里面就ok啦。
这个方法我想过,也用过,但感觉不如这种做法逻辑上通顺,所以想优先用动画传参的做法[/quote] 传参至少我所了解的就是这样子了,如果有找到了好的方法记得分享下~
templar616 2014-09-28
  • 打赏
  • 举报
回复
引用 8 楼 hgplan 的回复:
貌似现在Action调用的函数参数只能够支持一个float,或者一个Transform的情况。更多的参数和更多的参数类型是不支持这样做的吧。你可以把你的参数做成全局的呀,然后把某些具体要改变的数值写在函数里面就ok啦。
这个方法我想过,也用过,但感觉不如这种做法逻辑上通顺,所以想优先用动画传参的做法
加载更多回复(9)

8,303

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧