Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions Assets/StraightFour/Entity/Character/Scripts/CharacterEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,143 @@ public override string entityTag {
[Tooltip("Whether or not to fix the height if below ground.")]
public bool fixHeight = true;

/// <summary>
/// Set the character GameObject at runtime.
/// </summary>
/// <param name="newCharacterGO">The new character GameObject to use.</param>
/// <param name="synchronize">Whether or not to synchronize the change.</param>
/// <returns>Whether or not the setting was successful.</returns>
public bool SetCharacterGO(GameObject newCharacterGO, bool synchronize = true)
{
if (newCharacterGO == null)
{
LogSystem.LogError("[CharacterEntity->SetCharacterGO] Character GameObject cannot be null.");
return false;
}

// Store old character GameObject
GameObject oldCharacterGO = characterGO;

// Set the new character GameObject
characterGO = newCharacterGO;
characterGO.SetActive(true);
characterGO.transform.SetParent(transform);
characterGO.transform.localPosition = characterObjectOffset;
characterGO.transform.localRotation = characterObjectRotation;

// Update meshes for the new character GameObject
List<Mesh> ms = new List<Mesh>();
foreach (MeshFilter filt in characterGO.GetComponentsInChildren<MeshFilter>())
{
ms.Add(filt.sharedMesh);
}
SetRenderers(ms.ToArray());

// Calculate new bounds
Bounds bounds = new Bounds(Vector3.zero, Vector3.zero);
foreach (Mesh m in meshes)
{
m.RecalculateBounds();
bounds.Encapsulate(m.bounds);
}
originalMeshSize = bounds.size;

// Clean up old character GameObject
if (oldCharacterGO != null)
{
DestroyImmediate(oldCharacterGO);
}

if (synchronize && synchronizer != null)
{
// Note: Synchronization logic would go here if needed
}

return true;
}

/// <summary>
/// Set the character object offset at runtime.
/// </summary>
/// <param name="newOffset">The new offset to apply.</param>
/// <param name="synchronize">Whether or not to synchronize the change.</param>
/// <returns>Whether or not the setting was successful.</returns>
public bool SetCharacterObjectOffset(Vector3 newOffset, bool synchronize = true)
{
if (characterGO == null)
{
LogSystem.LogError("[CharacterEntity->SetCharacterObjectOffset] No character GameObject.");
return false;
}

characterObjectOffset = newOffset;
characterGO.transform.localPosition = characterObjectOffset;

if (synchronize && synchronizer != null)
{
// Note: Synchronization logic would go here if needed
}

return true;
}

/// <summary>
/// Set the character object rotation at runtime.
/// </summary>
/// <param name="newRotation">The new rotation to apply.</param>
/// <param name="synchronize">Whether or not to synchronize the change.</param>
/// <returns>Whether or not the setting was successful.</returns>
public bool SetCharacterObjectRotation(Quaternion newRotation, bool synchronize = true)
{
if (characterGO == null)
{
LogSystem.LogError("[CharacterEntity->SetCharacterObjectRotation] No character GameObject.");
return false;
}

characterObjectRotation = newRotation;
characterGO.transform.localRotation = characterObjectRotation;

if (synchronize && synchronizer != null)
{
// Note: Synchronization logic would go here if needed
}

return true;
}

/// <summary>
/// Set the character label offset at runtime.
/// </summary>
/// <param name="newOffset">The new offset to apply.</param>
/// <param name="synchronize">Whether or not to synchronize the change.</param>
/// <returns>Whether or not the setting was successful.</returns>
public bool SetCharacterLabelOffset(Vector3 newOffset, bool synchronize = true)
{
if (characterGO == null)
{
LogSystem.LogError("[CharacterEntity->SetCharacterLabelOffset] No character GameObject.");
return false;
}

characterLabelOffset = newOffset;

// Find the character label and update its position
TextMeshProUGUI[] labels = characterGO.GetComponentsInChildren<TextMeshProUGUI>();
foreach (TextMeshProUGUI label in labels)
{
label.transform.localPosition = characterLabelOffset;
break; // Assume there's only one label per character
}

if (synchronize && synchronizer != null)
{
// Note: Synchronization logic would go here if needed
}

return true;
}

/// <summary>
/// Minimum height to allow character entity to be at.
/// </summary>
Expand All @@ -89,6 +226,15 @@ public override string entityTag {
/// </summary>
private GameObject characterGO;

/// <summary>
/// Get the character GameObject.
/// </summary>
/// <returns>The current character GameObject.</returns>
public GameObject GetCharacterGO()
{
return characterGO;
}

/// <summary>
/// Meshes on the character model.
/// </summary>
Expand Down
110 changes: 110 additions & 0 deletions Assets/StraightFour/Testing/EntityTests/CharacterEntityRuntimeDemo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Copyright (c) 2019-2025 Five Squared Interactive. All rights reserved.

using UnityEngine;
using FiveSQD.StraightFour.Entity;
using System;

/// <summary>
/// Example script demonstrating the new runtime APIs for CharacterEntity
/// </summary>
public class CharacterEntityRuntimeDemo : MonoBehaviour
{
[Header("Character Entity Runtime API Demo")]
public CharacterEntity characterEntity;

[Header("Test Values")]
public Vector3 newOffset = new Vector3(0, 1, 0);
public Vector3 newRotationEuler = new Vector3(0, 45, 0);
public Vector3 newLabelOffset = new Vector3(0, 2, 0);
public GameObject newCharacterPrefab;

[Header("Controls")]
[Space]
public bool updateOffset;
public bool updateRotation;
public bool updateLabelOffset;
public bool updateCharacterGO;

void Update()
{
if (characterEntity == null) return;

// Update character object offset
if (updateOffset)
{
updateOffset = false;
bool success = characterEntity.SetCharacterObjectOffset(newOffset);
Debug.Log($"Set character object offset to {newOffset}: {(success ? "Success" : "Failed")}");
}

// Update character object rotation
if (updateRotation)
{
updateRotation = false;
Quaternion newRotation = Quaternion.Euler(newRotationEuler);
bool success = characterEntity.SetCharacterObjectRotation(newRotation);
Debug.Log($"Set character object rotation to {newRotationEuler}: {(success ? "Success" : "Failed")}");
}

// Update character label offset
if (updateLabelOffset)
{
updateLabelOffset = false;
bool success = characterEntity.SetCharacterLabelOffset(newLabelOffset);
Debug.Log($"Set character label offset to {newLabelOffset}: {(success ? "Success" : "Failed")}");
}

// Update character GameObject
if (updateCharacterGO && newCharacterPrefab != null)
{
updateCharacterGO = false;
bool success = characterEntity.SetCharacterGO(newCharacterPrefab);
Debug.Log($"Set character GameObject: {(success ? "Success" : "Failed")}");
}
}

[ContextMenu("Demo - Update All Properties")]
public void DemoUpdateAllProperties()
{
if (characterEntity == null)
{
Debug.LogError("No CharacterEntity assigned!");
return;
}

// Get current values
Vector3 currentOffset = characterEntity.characterObjectOffset;
Quaternion currentRotation = characterEntity.characterObjectRotation;
Vector3 currentLabelOffset = characterEntity.characterLabelOffset;
GameObject currentGO = characterEntity.GetCharacterGO();

Debug.Log("=== CharacterEntity Runtime API Demo ===");
Debug.Log($"Current Offset: {currentOffset}");
Debug.Log($"Current Rotation: {currentRotation.eulerAngles}");
Debug.Log($"Current Label Offset: {currentLabelOffset}");
Debug.Log($"Current GameObject: {(currentGO != null ? currentGO.name : "null")}");

// Update offset
Vector3 testOffset = currentOffset + Vector3.up;
if (characterEntity.SetCharacterObjectOffset(testOffset))
{
Debug.Log($"✓ Successfully updated offset to {testOffset}");
}

// Update rotation
Quaternion testRotation = currentRotation * Quaternion.Euler(0, 45, 0);
if (characterEntity.SetCharacterObjectRotation(testRotation))
{
Debug.Log($"✓ Successfully updated rotation to {testRotation.eulerAngles}");
}

// Update label offset
Vector3 testLabelOffset = currentLabelOffset + Vector3.forward;
if (characterEntity.SetCharacterLabelOffset(testLabelOffset))
{
Debug.Log($"✓ Successfully updated label offset to {testLabelOffset}");
}

Debug.Log("=== Demo Complete ===");
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading