1.シャベルの構成
シャベルは多くのパーツで構成されており、シャベルを持ち上げるときは、シャベルの任意の部分をクリックするだけです。
図のように、[木製ハンドル]、[ナット]、[シャベル]をクリックしてオブジェクトを持ち上げます。
(1) ハイライトをオンにする
(2) ソイルシャベルがクリックされるのを待つ: どの部分でもクリック可能
(3) ハイライトをオフにしてソイルシャベルを取り除く
第二に、実現のアイデア
非同期に実装: ウィジェットがクリックされるのを待つ
- 1. whenAny のキーコード: 任意のサブコンポーネントがクリックされるのを待つ
select でタスクリストをラップする方法に注意してください
var allTasks = mamoty.GetComponentsInChildren<Transform>().Select(t => t.gameObject.OnClickAsync());
await UniTask.WhenAny(allTasks);
- 2. クリックされるオブジェクトの非同期実装
(1) Collider コリジョン ボディで使用する
(2) コンポーネントとデリゲートのクリーニングに注意する
/// <summary>
/// 3D物体的异步点击方法
/// </summary>
/// <param name="gameObject"></param>
/// <returns></returns>
public static async UniTask OnClickAsync(this GameObject gameObject, EventTriggerType eventType = EventTriggerType.PointerClick)
{
//碰撞体判断
if (!gameObject.GetComponent<Collider>()) Debug.LogWarning($"{
gameObject}建议加上相应形状的collider组件");
//添加组件
var hasEventTrigger = gameObject.GetComponent<EventTrigger>() != null;
if (!hasEventTrigger) gameObject.AddComponent<EventTrigger>();
bool triggered = false;
//委托及实例方法
Action myAction = null;
Action fn = () =>
{
triggered = true;
};
//委托绑定
myAction += fn;
//事件触发
gameObject.GetComponent<EventTrigger>().AddListener(eventType, (PointerEventData eventData) =>
{
if (myAction != null)
{
myAction.Invoke();
}
});
//等待事件触发
await UniTask.WaitUntil(() => triggered == true);
Debug.Log("");
//取消绑定
myAction -= fn;
//资源清理:如果代码是并发执行,可能会把别人动态添加的eventTrigger销毁掉,所以建议不销毁
//if (!hasEventTrigger) GameObject.DestroyImmediate(gameObject.GetComponent<EventTrigger>());
return;
}
3. 土ショベルピッキングの主な工程
//取土铲
FlowGetMamoty = async () =>
{
//打开高亮
if (mamoty.GetComponent<Highlighter>() == null) mamoty.AddComponent<Highlighter>();
mamoty.GetComponent<Highlighter>().tween = true;
//等待土铲被点击:任一部件被点击
var allTasks = mamoty.GetComponentsInChildren<Transform>().Select(t => t.gameObject.OnClickAsync());
await UniTask.WhenAny(allTasks);
//关闭高亮,取走土铲
mamoty.GetComponent<Highlighter>().tween = false;
await mamoty.DoMove(openedPos, closedPos, closeDuration);
};