深く理解していないのでメモを残す
アニメーションフュージョン
新しいステートマシン
パネル上の動き
//モーション動作
//ロコモーション、動き、自分の名前
//ロコ、機関車
//ブレンド、混合
通常のパネルアニメーションとの違い
//通常のアニメーションのモーションはアニメーションクリップです
新しいビヘイビアツリー
// ダブルクリックして入力します
アニメーションを追加する
//ノードをクリックします
//右側の最初の小さな円をクリックしてアニメーションを追加します
//アニメーション項目が十分でない場合は、下の「+」をクリックしてください
(1Dの例) 歩くから走るまでスピードの大きさをコントロール
//右下隅にある他のモデルをドラッグできます
効果
// サイズが 3M の GIF カードで FAX するのは簡単ではありません
他のモデルを右下隅のウィンドウにドラッグできます。
(2Dの例)
Unity TimeLine アプリケーション チュートリアル クールなオープニング アニメーション 23-31
//デカルト、デカルト
//1. 2D を選択し (任意の 2D、メイン効果を試してください)、パラメータを選択します (水平は水平/左を意味し、垂直は垂直/前後を意味します) //2. ランダムに選択します (角速度コントロールの左右は参照できるかもしれませんが、他の要素はどの要素を参照するかわかりません)。3 の効果がある限り、ランダムに選択します
。
アニメーションのカット/調整
通常、モデルのすべてのアニメーションは一般的なクリップに配置され、カットされたか自分でカットされたかに関係なく、必要な状態のクリップが作成されます。
角速度
// 角速度はステアリングに大きな影響を与えます
// 方向転換は、「カニ」が横に歩くのではなく、向きを変えることに依存します
効果
(問題) Animator が空で開きます
リブート
私
アンチウッド
Unity TimeLine アプリケーション チュートリアルのクールなオープニング アニメーション 43-47
FixAnimatorIKPositionAndRotation (ボーン部分、特定の位置、重み) [カスタム関数]
[Tooltip("肩膀上的木头,一开始不激活")] public GameObject wood;
[Tooltip("模型中左手腕处")] public Transform leftHand;
[Tooltip("模型中右手腕处")] public Transform rightHand;
//
private void OnTriggerEnter(Collider other)//接触木头
{
if (other.tag == "Log")
{
Destroy(other.gameObject);
print("碰撞");
CarryWood();
}
}
private void CarryWood()//扛木头
{
wood.SetActive(true);
animator.SetBool(willHoldLogID,true);
}
private void OnAnimatorIK(int layerIndex)//每帧调用,需要层启用IK
{
if (layerIndex == 1)//对应HoldLog层
{
int weight = animator.GetBool(willHoldLogID) == true ? 1:0;//willHoldLogID的值
FixAnimatorIKPositionAndRotation(AvatarIKGoal.LeftHand,leftHand, weight);
FixAnimatorIKPositionAndRotation(AvatarIKGoal.RightHand,rightHand, weight);
}
}
private void FixAnimatorIKPositionAndRotation(AvatarIKGoal target, Transform match, int weight)//使用match的位置角度来调整target
{
animator.SetIKPosition(target, match.position);//设置位置
animator.SetIKRotation(target, match.rotation);
animator.SetIKPositionWeight(target, weight);//设置优先级
animator.SetIKRotationWeight(target, weight);
}
最初のパラメータのボーン部分
AvatarIKGoal.LeftHand
AvatarIKGoal.RightHand は
、このレイヤーのステート マシンが左手と右手のみを使用することを意味します。他の部分はその制御下にありません
2 番目のパラメータ、LeftHand/RightHand の位置
//具体的な操作は、木の下に 2 つの空のノードを作成し、「木への抵抗」中に左手と右手の Transform を保存することです。 //手を回転させて木にフィットさせ、効果を実現します。 //左手と右手の Transform を木の下の 2 つの空のノードに割り当て
ます
。左手と右手のリセット
3番目のパラメータIKはボーンの位置がターゲット(自分で設定)の位置のままであることを認識します
//原理は不明ですが、とにかく全て1(ターゲットの位置を特定)にしないと位置誤差が発生します
メソッドパラメータの比較
ターゲット マッチ MatchTarget
壁の向こう
// 緑色のボールは次のコードによって生成されます
animator.MatchTarget(matchTarget,
Quaternion.identity,
avatarTarget,
new MatchTargetWeightMask(matchTargetWeightMask, 0),
startTime,
endTime
);
private void Vault()//腾跃,尝试过和Slide重构复用,太麻烦
{
//1、播放动画
//速度>3 && 是 LocalMotion行为树
//射线检测
float testDistance = 4f;//检测距离
float vaultDistance = 3f;//起跳距离
bool willVault = false;//是否要进行翻墙
//rayPos,direction,射线,长度
bool isHit = Physics.Raycast(transform.position+Vector3.up*0.3f, transform.forward, out RaycastHit hit, testDistance);
if (isHit && hit.collider.tag == "Obstacle")//障碍物是墙
{
if (hit.distance > vaultDistance)//
{
willVault = true;
//
Vector3 point = hit.point;
point.y = hit.collider.transform.position.y + hit.collider.bounds.size.y;//位置加自身高度
matchTarget = point;//得到着手点
matchTarget.y +=matchTargetOffsetY;
}
}
animator.SetBool(willVaultID, willVault);
//2、MatchTarget
//有一个状态叫ClimbOver && 在翻墙中, 不在状态切换过程中(差值)
if (animator.GetCurrentAnimatorStateInfo(0).IsName("ClimbOver") && animator.IsInTransition(0) == false)
{
//1、MatchTarget
float startTime = 0.3f;
float endTime = 0.4f;
MatchTarget(matchTarget, AvatarTarget.LeftHand, Vector3.one, startTime, endTime);
}
}
void MatchTarget(Vector3 matchTarget,AvatarTarget avatarTarget, Vector3 matchTargetWeightMask, float startTime, float endTime)
{
//动画在(startTime,endTime)时
animator.MatchTarget(matchTarget,
Quaternion.identity,
avatarTarget,
new MatchTargetWeightMask(matchTargetWeightMask, 0),
startTime,
endTime
);
}
滑りやすい
//主にendTimeを調整します
//ビデオ matchTarget = hit.point+transform.forward * 2 (大きいほど遠く、エフェクトを見るときにビデオが10に設定され、スライドが遠くなります) // matchTargetは、(startTime, endTime)の期間内にモデル全体がどれだけ前に進むかを決定し
ます
void Slide()//滑地
{
//1、播放动画
//速度>3 && 是 LocalMotion行为树
if (animator.GetFloat(verticalID) > runSpeed && animator.GetCurrentAnimatorStateInfo(0).IsName("LocalMotion"))
{
//射线检测
float testDistance = 4f;//检测距离
float slideDistance = 2f;//滑地距离
bool willSlide = false;//是否要进行翻墙
//start,direction,射线,长度
bool isHit = Physics.Raycast(transform.position + Vector3.up * 1.5f, transform.forward, out RaycastHit hit, testDistance);
if (isHit && hit.collider.tag == "Obstacle")//障碍物是墙
{
if (hit.distance > slideDistance)//起跳距离
{
willSlide = true;
//设置match
Vector3 point = hit.point;
point.y = 0;//滑行不影响高度
point = point + transform.forward*10;
matchTarget = point;//滑行个2米
}
}
animator.SetBool(willSlideID, willSlide);
}
//
if (animator.IsInTransition(0) == false && animator.GetCurrentAnimatorStateInfo(0).IsName("Slide"))
{
//1、MatchTarget
float startTime = 0.38f;//0.17
float endTime = 0.67f;//0.67f;//30
//float startTime = 0.17f;//0.17
//float endTime = 0.30f;//0.67f;//30
MatchTarget(matchTarget, AvatarTarget.Root, new Vector3(1, 0, 1), startTime, endTime );
}
}
void MatchTarget(Vector3 matchTarget,AvatarTarget avatarTarget, Vector3 matchTargetWeightMask, float startTime, float endTime)
{
//动画在(startTime,endTime)时
animator.MatchTarget(matchTarget,
Quaternion.identity,
avatarTarget,
new MatchTargetWeightMask(matchTargetWeightMask, 0),
startTime,
endTime
);
}
監督
public PlayableDirector director;//过场动画的相机,播放时间轴
private void OnTriggerEnter(Collider other)//接触木头
{
if (other.tag == "Playable")
{
director.Play();//播放Timeline
}
}