teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

スクリプトを変更し実験した様子を追記

2020/04/20 12:11

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -44,4 +44,106 @@
44
44
  }
45
45
  }
46
46
  }
47
+ ```
48
+
49
+ **追記**
50
+
51
+ スクリプトをちょこっといじってみましたが、これだとどうでしょうか?
52
+
53
+ ```C#
54
+ using UnityEngine;
55
+
56
+ [DefaultExecutionOrder(1)]
57
+ public class ColliderUpdater : MonoBehaviour
58
+ {
59
+ private SkinnedMeshRenderer skinnedMeshRenderer;
60
+ private MeshCollider meshCollider;
61
+ private Mesh bakedMesh;
62
+
63
+ private void Start()
64
+ {
65
+ this.skinnedMeshRenderer = this.GetComponent<SkinnedMeshRenderer>();
66
+ if (this.skinnedMeshRenderer == null)
67
+ {
68
+ Debug.LogError("SkinnedMeshRenderer not found.");
69
+ }
70
+
71
+ this.meshCollider = this.GetComponent<MeshCollider>();
72
+ if (this.meshCollider == null)
73
+ {
74
+ this.meshCollider = this.gameObject.AddComponent<MeshCollider>();
75
+ }
76
+
77
+ this.bakedMesh = new Mesh();
78
+
79
+ // 「頻繁にデータ更新が行われるメッシュである」とマーキングしてみました
80
+ // 多少は動作が最適化されるかも...?
81
+ this.bakedMesh.MarkDynamic();
82
+ }
83
+
84
+ // 更新タイミングはFixedUpdateの方がいいかも...などと申し上げましたが
85
+ // Updateでもよさそうに思い直しまして、Updateでメッシュ更新を行っています
86
+ private void Update()
87
+ {
88
+ var scale = this.transform.localScale;
89
+ this.transform.localScale = Vector3.one;
90
+ this.skinnedMeshRenderer.BakeMesh(this.bakedMesh);
91
+ this.transform.localScale = scale;
92
+
93
+ // スケールを元に戻してからコライダーにメッシュをセットするようにしてみました
94
+ // 私の場合ですと、このようにしたところシーンビュー上のコライダーの
95
+ // 緑色メッシュ表示と実際の形状との食い違いが解消されました
96
+ this.meshCollider.sharedMesh = this.bakedMesh;
97
+ }
98
+ }
99
+ ```
100
+
101
+ キャラクターのアニメーションはご質問者さんのものをまねて下図のようにして...
102
+
103
+ ![図1](7fa991289a86f4484fa48e3a323bebb3.png)
104
+
105
+ シーンビューでコライダーの追従状況を見てみたところ、わずかな遅れはあるものの左右が逆転するような大きなズレはなさそうでした。
106
+
107
+ ![図2](dc794f751daf50e0946e890b8e1b9c80.gif)
108
+
109
+ マウスポインタの位置での当たり判定においても、コライダーは左右反転してはいないようです。もしコライダーが左右反転していればはっきり区別がつくだろうと思い、荒ぶっている髪の毛周辺に重点的にポインタを持っていきましたが、決定的に不自然な反応は見られませんでした。
110
+
111
+ ![図3](733804c4b4e3399edc6bc3965362e238.gif)
112
+
113
+ 念のため上図の実験で球にアタッチした当たり判定および色塗りスクリプトも追記しますが、とりわけ特殊なことはしておらず`Physics.Raycast`を使った判定を行っているだけです。
114
+
115
+ ```C#
116
+ using UnityEngine;
117
+
118
+ public class SphereController : MonoBehaviour
119
+ {
120
+ private Camera mainCamera;
121
+ private Material material;
122
+
123
+ private void Start()
124
+ {
125
+ var r = this.GetComponent<Renderer>();
126
+ if (r == null)
127
+ {
128
+ this.enabled = false;
129
+ return;
130
+ }
131
+
132
+ Cursor.visible = false;
133
+ this.material = r.material;
134
+ this.mainCamera = Camera.main;
135
+ }
136
+
137
+ private void Update()
138
+ {
139
+ var ray = this.mainCamera.ScreenPointToRay(Input.mousePosition);
140
+ var plane = new Plane(Vector3.back, 0);
141
+ if (plane.Raycast(ray, out var enter))
142
+ {
143
+ this.transform.position = ray.GetPoint(enter);
144
+ }
145
+
146
+ this.material.color = Physics.Raycast(ray) ? Color.green : Color.red;
147
+ }
148
+ }
47
149
  ```