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:
parent
0306045697
commit
beb17eacdf
141 changed files with 287727 additions and 1 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4386b74c02bd9624e9f7f3e6ac485fa8
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 388758
|
||||
packageName: Low Poly Character Collection 3
|
||||
packageVersion: 1.1
|
||||
assetPath: Assets/Hodaart/HodaartLowPolyCharacterCollection3/Scene/Scripts/CharacterSelectionController.cs
|
||||
uploadId: 946460
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
|
||||
namespace LowPolyCharacterCollection3
|
||||
{
|
||||
public class DragRotateController : MonoBehaviour,
|
||||
IPointerDownHandler, IDragHandler, IPointerUpHandler
|
||||
{
|
||||
[SerializeField] private Transform targetToRotate;
|
||||
[SerializeField] private float rotationSpeed = 0.3f;
|
||||
[SerializeField] private float smoothSpeed = 10f;
|
||||
|
||||
private float targetY;
|
||||
private float currentY;
|
||||
private float lastPointerX;
|
||||
private bool isDragging;
|
||||
|
||||
void Start()
|
||||
{
|
||||
currentY = targetY = targetToRotate.eulerAngles.y;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
currentY = Mathf.Lerp(currentY, targetY, Time.deltaTime * smoothSpeed);
|
||||
targetToRotate.rotation = Quaternion.Euler(0f, currentY, 0f);
|
||||
}
|
||||
|
||||
public void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
isDragging = true;
|
||||
lastPointerX = eventData.position.x;
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
if (!isDragging) return;
|
||||
|
||||
float deltaX = eventData.position.x - lastPointerX;
|
||||
lastPointerX = eventData.position.x;
|
||||
|
||||
targetY -= deltaX * rotationSpeed;
|
||||
}
|
||||
|
||||
public void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
isDragging = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0a1d299c242c80049827da9acd6d0722
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 388758
|
||||
packageName: Low Poly Character Collection 3
|
||||
packageVersion: 1.1
|
||||
assetPath: Assets/Hodaart/HodaartLowPolyCharacterCollection3/Scene/Scripts/DragRotateController.cs
|
||||
uploadId: 946460
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using UnityEngine.InputSystem.UI;
|
||||
#endif
|
||||
|
||||
namespace LowPolyCharacterCollection3
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public class EventSystemEnsurer : MonoBehaviour
|
||||
{
|
||||
private void Awake()
|
||||
{
|
||||
if (FindObjectOfType<EventSystem>() == null)
|
||||
{
|
||||
var go = new GameObject("EventSystem");
|
||||
go.AddComponent<EventSystem>();
|
||||
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
|
||||
go.AddComponent<InputSystemUIInputModule>();
|
||||
Debug.Log("[EventSystemEnsurer] No EventSystem found — created one with InputSystemUIInputModule.");
|
||||
#else
|
||||
go.AddComponent<StandaloneInputModule>();
|
||||
Debug.Log("[EventSystemEnsurer] No EventSystem found — created one with StandaloneInputModule.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7cda49a436f661a4fb324c56751db957
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 388758
|
||||
packageName: Low Poly Character Collection 3
|
||||
packageVersion: 1.1
|
||||
assetPath: Assets/Hodaart/HodaartLowPolyCharacterCollection3/Scene/Scripts/EventSystemEnsurer.cs
|
||||
uploadId: 946460
|
||||
Loading…
Add table
Add a link
Reference in a new issue