
瓦尔海姆的部队战争和agar.io
部队球球大作战与战争的想法
查看大图enemy ai
using UnityEngine;
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour
{
public NavMeshAgent agent;
[Header("Orb Searching")]
public float searchRange = 100f;
[Header("Orb Collection")]
public float collectDistance = 2f;
private Transform targetOrb;
private OrbCollector collector;
void Start()
{
agent = GetComponent<NavMeshAgent>();
collector = GetComponent<OrbCollector>();
if(collector == null)
{
Debug.LogWarning(
"Enemy needs an OrbCollector component!");
}
InvokeRepeating(
"FindOrb",
0,
2);
}
void Update()
{
if(targetOrb != null)
{
agent.SetDestination(
targetOrb.position);
float distance =
Vector3.Distance(
transform.position,
targetOrb.position);
if(distance <= collectDistance)
{
CollectOrb();
}
}
}
void FindOrb()
{
GameObject[] orbs =
GameObject.FindGameObjectsWithTag("Orb");
float closest =
Mathf.Infinity;
GameObject best = null;
foreach(GameObject orb in orbs)
{
float distance =
Vector3.Distance(
transform.position,
orb.transform.position);
if(distance < closest &&
distance <= searchRange)
{
closest = distance;
best = orb;
}
}
if(best != null)
{
targetOrb =
best.transform;
}
}
void CollectOrb()
{
if(collector != null)
{
collector.CollectOrb(1);
}
Destroy(
targetOrb.gameObject);
targetOrb = null;
}
}
end
enemy spawn
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
public GameObject enemyPrefab;
public Terrain terrain;
public int enemyAmount = 50;
void Start()
{
SpawnEnemies();
}
void SpawnEnemies()
{
TerrainData data =
terrain.terrainData;
Vector3 terrainPos =
terrain.transform.position;
for(int i = 0; i < enemyAmount; i++)
{
float x =
Random.Range(
0,
data.size.x);
float z =
Random.Range(
0,
data.size.z);
float y =
data.GetHeight(
(int)x,
(int)z);
Vector3 spawn =
new Vector3(
x,
y,
z)
+ terrainPos;
Instantiate(
enemyPrefab,
spawn,
Quaternion.identity);
}
}
}
end
orb
using UnityEngine;
public class Orb : MonoBehaviour
{
public int orbValue = 1;
public float rotateSpeed = 100f;
private void Update()
{
transform.Rotate(Vector3.up * rotateSpeed * Time.deltaTime);
}
private void OnTriggerEnter(Collider other)
{
OrbCollector collector = other.GetComponent<OrbCollector>();
if (collector != null)
{
collector.CollectOrb(orbValue);
Destroy(gameObject);
}
}
}
end
orb collector
using UnityEngine;
public class OrbCollector : MonoBehaviour
{
[Header("Collector")]
public string collectorName;
[Header("Orb Storage")]
public int orbs = 0;
[Header("Troop Spawning")]
public GameObject troopPrefab;
public Transform troopSpawnPoint;
public int orbsPerTroop = 5;
public int troopsSpawned = 0;
public void CollectOrb(int amount)
{
orbs += amount;
Debug.Log(
collectorName +
" has " +
orbs +
" orbs");
CheckSpawn();
}
void CheckSpawn()
{
while(orbs >= orbsPerTroop)
{
SpawnTroop();
orbs -= orbsPerTroop;
}
}
void SpawnTroop()
{
if(troopPrefab == null)
{
Debug.LogWarning(
"No troop prefab assigned");
return;
}
Vector3 spawnPosition;
if(troopSpawnPoint != null)
{
spawnPosition =
troopSpawnPoint.position;
}
else
{
spawnPosition =
transform.position +
transform.forward * 3;
}
GameObject troop =
Instantiate(
troopPrefab,
spawnPosition,
Quaternion.identity);
TroopAI ai =
troop.GetComponent<TroopAI>();
if(ai != null)
{
ai.owner =
transform;
}
troopsSpawned++;
Debug.Log(
"Spawned troop " +
troopsSpawned);
}
}
end
orb spawn
using UnityEngine;
public class OrbSpawner : MonoBehaviour
{
public GameObject orbPrefab;
public Terrain terrain;
public int amount = 200;
public float heightOffset = 1f;
void Start()
{
SpawnAllOrbs();
}
void SpawnAllOrbs()
{
if(terrain == null)
{
Debug.LogError("No terrain assigned");
return;
}
TerrainData data = terrain.terrainData;
Vector3 terrainPosition =
terrain.transform.position;
for(int i = 0; i < amount; i++)
{
float x =
Random.Range(
0,
data.size.x);
float z =
Random.Range(
0,
data.size.z);
float y =
data.GetHeight(
(int)x,
(int)z);
Vector3 position =
new Vector3(
x,
y + heightOffset,
z)
+ terrainPosition;
Instantiate(
orbPrefab,
position,
Quaternion.identity);
}
}
}
end
troop ai
using UnityEngine;
using UnityEngine.AI;
public class TroopAI : MonoBehaviour
{
[Header("Owner")]
public Transform owner;
[Header("Movement")]
public NavMeshAgent agent;
public float followDistance = 5f;
public float updateRate = 0.5f;
[Header("Combat")]
public float health = 100;
public float damage = 10;
private float timer;
void Start()
{
agent =
GetComponent<NavMeshAgent>();
}
void Update()
{
if(owner == null)
{
return;
}
timer += Time.deltaTime;
if(timer >= updateRate)
{
FollowOwner();
timer = 0;
}
}
void FollowOwner()
{
float distance =
Vector3.Distance(
transform.position,
owner.position);
if(distance > followDistance)
{
agent.SetDestination(
owner.position);
}
else
{
agent.ResetPath();
}
}
public void TakeDamage(float amount)
{
health -= amount;
if(health <= 0)
{
Destroy(gameObject);
}
}
}
end
view
using UnityEngine;
using System.Collections.Generic;
public class EnemyWatchCamera : MonoBehaviour
{
[Header("Camera")]
public Camera playerCamera;
public Camera watchCamera;
[Header("AI Settings")]
public string aiTag = "Enemy";
public float orbitDistance = 6f;
public float orbitHeight = 3f;
public float orbitSpeed = 120f;
[Header("Controls")]
public KeyCode watchKey = KeyCode.V;
public KeyCode nextTargetKey = KeyCode.C;
private List<GameObject> targets = new List<GameObject>();
private int currentTarget = 0;
private bool watching = false;
private float orbitAngle;
void Start()
{
watchCamera.enabled = false;
playerCamera.enabled = true;
FindTargets();
}
void Update()
{
if(Input.GetKeyDown(watchKey))
{
ToggleWatch();
}
if(watching && Input.GetKeyDown(nextTargetKey))
{
NextTarget();
}
if(watching)
{
OrbitCamera();
}
}
void FindTargets()
{
targets.Clear();
GameObject[] enemies = GameObject.FindGameObjectsWithTag(aiTag);
foreach(GameObject enemy in enemies)
{
targets.Add(enemy);
}
}
void ToggleWatch()
{
watching = !watching;
if(watching)
{
FindTargets();
playerCamera.enabled = false;
watchCamera.enabled = true;
currentTarget = 0;
}
else
{
watchCamera.enabled = false;
playerCamera.enabled = true;
}
}
void NextTarget()
{
FindTargets();
if(targets.Count == 0)
return;
currentTarget++;
if(currentTarget >= targets.Count)
{
currentTarget = 0;
}
}
void OrbitCamera()
{
if(targets.Count == 0)
return;
GameObject target = targets[currentTarget];
if(target == null)
return;
orbitAngle += Input.GetAxis("Mouse X") * orbitSpeed * Time.deltaTime;
Vector3 offset = new Vector3(
Mathf.Sin(orbitAngle * Mathf.Deg2Rad) * orbitDistance,
orbitHeight,
Mathf.Cos(orbitAngle * Mathf.Deg2Rad) * orbitDistance
);
watchCamera.transform.position =
target.transform.position + offset;
watchCamera.transform.LookAt(
target.transform.position + Vector3.up
);
}
}
end
obelisk
using UnityEngine;
using System.Collections.Generic;
public class TerrainObeliskSpawner : MonoBehaviour
{
[Header("Terrain")]
public Terrain terrain;
[Header("Obelisk Prefab")]
public GameObject obeliskPrefab;
[Header("Spawn Settings")]
public int amountToSpawn = 20;
public float minDistanceBetweenObelisks = 50f;
public float spawnHeightOffset = 1f;
[Header("Lifetime")]
public bool enableDecay = true;
public float decayTime = 300f;
public float respawnTime = 60f;
private List<GameObject> spawnedObelisks = new List<GameObject>();
void Start()
{
SpawnObelisks();
}
public void SpawnObelisks()
{
int attempts = 0;
int maxAttempts = amountToSpawn * 50;
while (spawnedObelisks.Count < amountToSpawn && attempts < maxAttempts)
{
attempts++;
Vector3 spawnPosition = GetRandomTerrainPosition();
if (IsValidPosition(spawnPosition))
{
GameObject obelisk = Instantiate(
obeliskPrefab,
spawnPosition,
Quaternion.identity
);
spawnedObelisks.Add(obelisk);
if(enableDecay)
{
StartCoroutine(DecayObelisk(obelisk));
}
}
}
}
Vector3 GetRandomTerrainPosition()
{
Vector3 terrainSize = terrain.terrainData.size;
float x = Random.Range(0, terrainSize.x);
float z = Random.Range(0, terrainSize.z);
float y = terrain.SampleHeight(
new Vector3(x,0,z)
);
return terrain.transform.position +
new Vector3(
x,
y + spawnHeightOffset,
z
);
}
bool IsValidPosition(Vector3 position)
{
foreach(GameObject obj in spawnedObelisks)
{
if(obj == null)
continue;
float distance = Vector3.Distance(
position,
obj.transform.position
);
if(distance < minDistanceBetweenObelisks)
return false;
}
return true;
}
System.Collections.IEnumerator DecayObelisk(GameObject obelisk)
{
yield return new WaitForSeconds(decayTime);
if(obelisk != null)
{
spawnedObelisks.Remove(obelisk);
Destroy(obelisk);
}
yield return new WaitForSeconds(respawnTime);
SpawnSingleObelisk();
}
void SpawnSingleObelisk()
{
int attempts = 0;
while(attempts < 100)
{
attempts++;
Vector3 pos = GetRandomTerrainPosition();
if(IsValidPosition(pos))
{
GameObject obelisk = Instantiate(
obeliskPrefab,
pos,
Quaternion.identity
);
spawnedObelisks.Add(obelisk);
if(enableDecay)
StartCoroutine(DecayObelisk(obelisk));
break;
}
}
}
}
end
room
using UnityEngine;
using System.Collections;
public class ObeliskRoomInterior : MonoBehaviour
{
[Header("Player")]
public Transform player;
[Header("Room Prefab")]
public GameObject roomPrefab;
[Header("Room Settings")]
public Transform outsideExitPoint;
public float enterDistance = 4f;
public float roomDepth = -500f;
[Header("Spawn Protection")]
public float spawnHeightOffset = 1.5f;
public float teleportDelay = 0.1f;
[Header("Terrain Border")]
public Terrain terrain;
public float borderDistance = 30f;
[Header("Input")]
public KeyCode enterKey = KeyCode.E;
public KeyCode exitKey = KeyCode.F;
private GameObject spawnedRoom;
private bool playerInside = false;
void Update()
{
if (!playerInside)
{
float distance = Vector3.Distance(
player.position,
transform.position
);
if(distance <= enterDistance)
{
if(Input.GetKeyDown(enterKey))
{
EnterRoom();
}
}
}
else
{
if(Input.GetKeyDown(exitKey))
{
ExitRoom();
}
}
}
void EnterRoom()
{
playerInside = true;
Vector3 roomPosition = new Vector3(
transform.position.x,
roomDepth,
transform.position.z
);
// 保持房间远离地形边界
if(terrain != null)
{
Vector3 terrainPos = terrain.transform.position;
Vector3 terrainSize = terrain.terrainData.size;
roomPosition.x = Mathf.Clamp(
roomPosition.x,
terrainPos.x + borderDistance,
terrainPos.x + terrainSize.x - borderDistance
);
roomPosition.z = Mathf.Clamp(
roomPosition.z,
terrainPos.z + borderDistance,
terrainPos.z + terrainSize.z - borderDistance
);
}
spawnedRoom = Instantiate(
roomPrefab,
roomPosition,
Quaternion.identity
);
ObeliskRoomExit exit =
spawnedRoom.GetComponentInChildren<ObeliskRoomExit>();
if(exit != null)
{
exit.owner = this;
exit.player = player;
exit.outsidePosition = outsideExitPoint.position;
}
Transform insideSpawn =
spawnedRoom.transform.Find("InsideSpawn");
if(insideSpawn != null)
{
StartCoroutine(TeleportInside(insideSpawn));
}
else
{
StartCoroutine(TeleportInside(spawnedRoom.transform));
}
}
IEnumerator TeleportInside(Transform spawn)
{
// 等待房间碰撞体加载
yield return new WaitForSeconds(teleportDelay);
CharacterController controller =
player.GetComponent<CharacterController>();
if(controller != null)
{
controller.enabled = false;
}
player.position = spawn.position + Vector3.up * spawnHeightOffset;
if(controller != null)
{
controller.enabled = true;
}
}
public void ExitRoom()
{
playerInside = false;
CharacterController controller =
player.GetComponent<CharacterController>();
if(controller != null)
{
controller.enabled = false;
}
player.position = outsideExitPoint.position;
if(controller != null)
{
controller.enabled = true;
}
if(spawnedRoom != null)
{
Destroy(spawnedRoom);
}
}
}
end
room exit
using UnityEngine;
public class ObeliskRoomExit : MonoBehaviour
{
[HideInInspector]
public ObeliskRoomInterior owner;
[HideInInspector]
public Transform player;
public Vector3 outsidePosition;
public KeyCode exitKey = KeyCode.F;
void Update()
{
if(player == null)
return;
float distance =
Vector3.Distance(
player.position,
transform.position
);
if(distance < 3f)
{
if(Input.GetKeyDown(exitKey))
{
Exit();
}
}
}
void Exit()
{
owner.ExitRoom();
}
}
end
troop storage
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class SimpleObeliskTroopStorage : MonoBehaviour
{
[Header("Storage")]
public int maxTroops = 20;
public float storageRange = 5f;
[Header("Release")]
public float releaseDistance = 2f;
[Header("Controls")]
public KeyCode storeKey = KeyCode.G;
public KeyCode releaseKey = KeyCode.R;
private List<GameObject> storedTroops = new List<GameObject>();
void Update()
{
if(Input.GetKeyDown(storeKey))
{
StoreTroop();
}
if(Input.GetKeyDown(releaseKey))
{
ReleaseTroop();
}
}
void StoreTroop()
{
if(storedTroops.Count >= maxTroops)
{
Debug.Log("方尖碑存储已满");
return;
}
Collider[] nearby =
Physics.OverlapSphere(
transform.position,
storageRange
);
foreach(Collider col in nearby)
{
TroopAI troop =
col.GetComponentInParent<TroopAI>();
if(troop != null)
{
GameObject troopObject =
troop.gameObject;
storedTroops.Add(troopObject);
troopObject.SetActive(false);
Debug.Log(
"已存储部队: "
+ troopObject.name
);
return;
}
}
Debug.Log("附近没有部队");
}
void ReleaseTroop()
{
if(storedTroops.Count == 0)
{
Debug.Log("没有已存储的部队");
return;
}
GameObject troop =
storedTroops[0];
storedTroops.RemoveAt(0);
Vector3 spawnPosition =
transform.position +
transform.forward * releaseDistance;
troop.transform.position =
spawnPosition;
troop.transform.rotation =
transform.rotation;
troop.SetActive(true);
NavMeshAgent agent =
troop.GetComponent<NavMeshAgent>();
if(agent != null)
{
agent.enabled = true;
agent.Warp(spawnPosition);
}
Debug.Log(
"已释放部队: "
+ troop.name
);
}
public int GetStoredTroopCount()
{
return storedTroops.Count;
}
void OnDrawGizmosSelected()
{
Gizmos.DrawWireSphere(
transform.position,
storageRange
);
}
}
end
还没有人评论,去客户端里说两句吧。
评论在新手盒子客户端中发表,这里同步展示。