概要
タイトルのままです。
UnityのCharacterControllerは便利ですが、アタッチしているゲームオブジェクトとの紐づきが強いです。
キャラクターの移動をさせたいからといって、別にそのオブジェクトを動かしたいとは限りません。
幸い、結果は即時適用されるようなのでその結果だけ抜き出すことができました。
対応
一度移動を適用して結果だけ抜き出してもとに戻す拡張メソッドを作成します。
CharacterControllerExtensions.cs
using UnityEngine;
namespace TsujihaTools.Extensions
{
public static class CharacterControllerExtensions
{
/// <summary>
/// CharacterControllerに従って移動させた場合の移動量を取得する
/// </summary>
/// <param name="self">CharacterController</param>
/// <param name="move">移動量</param>
/// <returns></returns>
public static Vector3 SimulateMove(this CharacterController self, Vector3 move)
{
// CharacterControllerに従って移動させる.
var prevPos = self.transform.position;
self.Move(move);
var nextPos = self.transform.position;
// 元に戻す.
self.transform.position = prevPos;
// 結果だけ引き抜く.
return nextPos - prevPos;
}
}
}
使用例
CharacterControllerExtensions.cs
// 移動量.
var move = nextPosition - prevPosition;
// CharacterControllerに従って移動させ、結果だけ引き抜く.
var moveResult = col.SimulateMove(move);
// 結果を移動対象に適用させる.
MoveTarget.transform.Translate(moveResult);
結果(CollisionFlags)を受け取りたい場合
CharacterControllerExtensions.cs
using UnityEngine;
namespace TsujihaTools.Extensions
{
public static class CharacterControllerExtensions
{
/// <summary>
/// CharacterControllerに従って移動させた場合の移動量を取得する
/// </summary>
/// <param name="self">CharacterController</param>
/// <param name="move">移動量</param>
/// <returns></returns>
public static CollisionFlags SimulateMove(this CharacterController self, Vector3 move, out Vector3 simulate)
{
// CharacterControllerに従って移動させる.
var prevPos = self.transform.position;
var result = self.Move(move);
var nextPos = self.transform.position;
// 元に戻す.
self.transform.position = prevPos;
// 結果だけ引き抜く.
simulate = nextPos - prevPos;
return result;
}
}
}
以上です。