feat: Implement NavMesh pathfinding and Deep Social visuals
- Phase 20-F: NavMesh Integration - Added 'com.unity.ai.navigation' package - Implemented Runtime NavMesh Baking in EnvironmentManager - Added NavMeshObstacle to environmental assets - Updated AgentVisual to use NavMeshAgent for movement - Implemented 'Instinctive Avoidance' via target offsetting - Phase 21: Social Interaction & Expressions - Added procedural Dance and Wave animations in AgentAnimator - Implemented 'Dance Party' triggering logic in engine.py and AgentVisual - Added social relationship syncing (Backend -> Frontend) - Implemented proximity-based social greetings (Heart emote + Wave) - Updated Models.cs to support relationship data parsing
This commit is contained in:
@@ -202,9 +202,31 @@ class GameEngine:
|
||||
"""Broadcast all agents' current status."""
|
||||
with get_db_session() as db:
|
||||
agents = db.query(Agent).all()
|
||||
agents_data = [agent.to_dict() for agent in agents]
|
||||
agents_data = []
|
||||
for agent in agents:
|
||||
data = agent.to_dict()
|
||||
# Phase 21-B: Inject relationships
|
||||
data["relationships"] = self._get_agent_relationships(db, agent.id)
|
||||
agents_data.append(data)
|
||||
await self._broadcast_event(EventType.AGENTS_UPDATE, {"agents": agents_data})
|
||||
|
||||
def _get_agent_relationships(self, db, agent_id: int) -> list:
|
||||
"""Fetch significant relationships for an agent."""
|
||||
# Phase 21-B: Only send non-stranger relationships to save bandwidth
|
||||
rels = db.query(AgentRelationship).filter(
|
||||
AgentRelationship.agent_from_id == agent_id,
|
||||
AgentRelationship.relationship_type != "stranger"
|
||||
).all()
|
||||
|
||||
results = []
|
||||
for r in rels:
|
||||
results.append({
|
||||
"target_id": r.agent_to_id,
|
||||
"type": r.relationship_type,
|
||||
"affection": r.affection
|
||||
})
|
||||
return results
|
||||
|
||||
async def _broadcast_world_status(self) -> None:
|
||||
"""Broadcast world state."""
|
||||
with get_db_session() as db:
|
||||
@@ -719,11 +741,31 @@ class GameEngine:
|
||||
target_name = friend.name
|
||||
should_update = True
|
||||
|
||||
# 3. Boredom / Wandering
|
||||
elif agent.current_action == "Idle" or agent.current_action is None:
|
||||
# Phase 21: Social Interaction (Group Dance)
|
||||
# If Happy (>80) and near others, chance to start dancing
|
||||
elif agent.mood > 80 and agent.current_action != "Dance":
|
||||
# Check for nearby agents (same location)
|
||||
nearby_count = 0
|
||||
for other in agents:
|
||||
if other.id != agent.id and other.status == "Alive" and other.location == agent.location:
|
||||
nearby_count += 1
|
||||
|
||||
# Dance Party Trigger! (Need at least 1 friend, 10% chance)
|
||||
if nearby_count >= 1 and random.random() < 0.10:
|
||||
new_action = "Dance"
|
||||
# Keep location same
|
||||
new_location = agent.location
|
||||
should_update = True
|
||||
|
||||
# 2. Idle Behavior (Default)
|
||||
elif agent.current_action not in ["Sleep", "Chat", "Dance"]:
|
||||
# Random chance to move nearby or chat
|
||||
if random.random() < 0.3:
|
||||
new_action = "Wander"
|
||||
new_location = "nearby"
|
||||
new_location = "nearby" # Will be randomized in Unity/GameManager mapping
|
||||
should_update = True
|
||||
elif random.random() < 0.1:
|
||||
new_action = "Idle"
|
||||
should_update = True
|
||||
|
||||
# 4. Finish Tasks (Simulation)
|
||||
|
||||
@@ -212,7 +212,7 @@ class LLMService:
|
||||
f"Personality: {agent.personality}. "
|
||||
f"Current Status: HP={agent.hp}, Energy={agent.energy}. "
|
||||
f"Shelter Status: {'Under shelter (safe from weather)' if agent.is_sheltered else 'Exposed (vulnerable to weather)'}. "
|
||||
f"You live on a survival island. "
|
||||
f"You are a land creature on a survival island. You have a natural instinct to stay on the dry sand and avoid the deep ocean. "
|
||||
f"Relevant Memories:\n{memory_context}\n"
|
||||
f"React to the following event briefly (under 20 words). "
|
||||
f"Respond in first person, as if speaking out loud."
|
||||
@@ -278,7 +278,7 @@ class LLMService:
|
||||
f"Personality: {agent.personality}. "
|
||||
f"Current Status: HP={agent.hp}, Energy={agent.energy}. "
|
||||
f"Shelter Status: {'Under shelter (protected)' if agent.is_sheltered else 'Exposed to elements'}. "
|
||||
f"You are stranded on a survival island. "
|
||||
f"You are a land creature stranded on a survival island beach. You feel safer on dry land than near the waves. "
|
||||
f"It is currently {time_of_day} and the weather is {weather}. "
|
||||
f"Say something brief (under 15 words) about your situation or thoughts. "
|
||||
f"Speak naturally, as if talking to yourself or nearby survivors."
|
||||
|
||||
Reference in New Issue
Block a user