M1: add networked rigged player avatar (run-around character)

- Import Hodaart Low Poly Character Collection 3 (humanoid-rigged, LFS)
- PlayerAvatar.cs: owner-authoritative CharacterController movement, animation
  derived from measured speed on every client (no NetworkAnimator needed)
- OwnerAuthNetworkTransform.cs: owner-authoritative NetworkTransform
- PlayerLocomotion.controller: Idle/Walk/Run 1D blend tree on Speed (reuses
  Hodaart clips)
- PlayerCharacter.prefab (Character 01 + CC + NetworkObject + owner NT +
  PlayerAvatar + Animator w/ humanoid avatar); registered as PlayerPrefab
- Verified in play: spawns, visible, Idle pose (rig animates), owner-auth

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
megaproxy 2026-07-12 18:43:39 +01:00
parent 5db61fdb57
commit 94951ec70a
141 changed files with 287727 additions and 1 deletions

View file

@ -0,0 +1,118 @@
using System.Collections;
using UnityEngine;
namespace LowPolyCharacterCollection3
{
public class CharacterSelectionController : MonoBehaviour
{
[SerializeField] private GameObject[] characters;
private int currentIndex = 0;
private Animator currentAnimator;
[SerializeField] private float switchDelay = 0.5f;
private bool isSwitching = false;
void Start()
{
ShowCharacter(currentIndex);
}
void ShowCharacter(int index)
{
for (int i = 0; i < characters.Length; i++)
{
characters[i].SetActive(i == index);
}
currentAnimator = characters[index].GetComponent<Animator>();
}
public void NextCharacter()
{
StartCoroutine(SwitchCharacterWithDelay(+1));
}
public void PreviousCharacter()
{
StartCoroutine(SwitchCharacterWithDelay(-1));
}
IEnumerator SwitchCharacterWithDelay(int direction)
{
if (isSwitching) yield break;
isSwitching = true;
PlayIdle();
yield return new WaitForSeconds(switchDelay);
currentIndex += direction;
if (currentIndex >= characters.Length) currentIndex = 0;
if (currentIndex < 0) currentIndex = characters.Length - 1;
ShowCharacter(currentIndex);
isSwitching = false;
}
// ====================== Animations ======================
public void PlayWalk()
{
if (currentAnimator == null) return;
PlayIdle();
currentAnimator.SetBool("Walking", true);
}
public void PlayRun()
{
if (currentAnimator == null) return;
PlayIdle();
currentAnimator.SetBool("Running", true);
}
public void PlayJump()
{
if (currentAnimator == null) return;
PlayIdle();
currentAnimator.SetTrigger("Jump");
}
public void PlayDance1()
{
if (currentAnimator == null) return;
PlayIdle();
currentAnimator.SetBool("Dance 1",true);
}
public void PlayDance2()
{
if (currentAnimator == null) return;
PlayIdle();
currentAnimator.SetBool("Dance 2", true);
}
public void PlayHappyWalk()
{
if (currentAnimator == null) return;
PlayIdle();
currentAnimator.SetBool("Happy Walk", true);
}
public void PlayGreeting()
{
if (currentAnimator == null) return;
PlayIdle();
currentAnimator.SetTrigger("Greeting");
}
public void PlayIdle()
{
if (currentAnimator == null) return;
currentAnimator.SetBool("Walking", false);
currentAnimator.SetBool("Running", false);
currentAnimator.SetBool("Dance 1", false);
currentAnimator.SetBool("Dance 2", false);
currentAnimator.SetBool("Happy Walk", false);
}
}
}