
部队战争
球球大作战部队全面战争系统,并为其配备法术
查看大图敌人 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;
}
}
结束
敌人生成
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);
}
}
}
结束
第一人称视角
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class FPVPlayerController : MonoBehaviour
{
[Header("Player Camera")]
public Camera playerCamera;
[Header("Movement")]
public float walkSpeed = 5f;
public float sprintSpeed = 9f;
public float crouchSpeed = 2.5f;
[Header("Jump")]
public float jumpHeight = 2f;
public int maxJumps = 2;
[Header("Gravity")]
public float gravity = -20f;
[Header("Mouse Look")]
public float mouseSensitivity = 200f;
[Header("Crouch")]
public float standingHeight = 2f;
public float crouchHeight = 1f;
public float cameraStandHeight = 0.8f;
public float cameraCrouchHeight = 0.4f;
public float crouchSmooth = 10f;
private CharacterController controller;
private Vector3 velocity;
private float xRotation;
private int jumpsLeft;
private bool crouching;
void Start()
{
controller =
GetComponent<CharacterController>();
Cursor.lockState =
CursorLockMode.Locked;
Cursor.visible = false;
jumpsLeft = maxJumps;
}
void Update()
{
Look();
Move();
Jump();
Crouch();
ApplyGravity();
}
void Look()
{
float mouseX =
Input.GetAxis("Mouse X")
* mouseSensitivity
* Time.deltaTime;
float mouseY =
Input.GetAxis("Mouse Y")
* mouseSensitivity
* Time.deltaTime;
xRotation -= mouseY;
xRotation =
Mathf.Clamp(
xRotation,
-90f,
90f);
playerCamera.transform.localRotation =
Quaternion.Euler(
xRotation,
0,
0);
transform.Rotate(
Vector3.up *
mouseX);
}
void Move()
{
float x =
Input.GetAxis("Horizontal");
float z =
Input.GetAxis("Vertical");
Vector3 move =
transform.right * x +
transform.forward * z;
float speed = walkSpeed;
if(Input.GetKey(KeyCode.LeftShift)
&& !crouching)
{
speed = sprintSpeed;
}
if(crouching)
{
speed = crouchSpeed;
}
controller.Move(
move *
speed *
Time.deltaTime);
}
void Jump()
{
if(controller.isGrounded)
{
jumpsLeft = maxJumps;
}
if(Input.GetKeyDown(KeyCode.Space)
&& jumpsLeft > 0)
{
velocity.y =
Mathf.Sqrt(
jumpHeight *
-2f *
gravity);
jumpsLeft--;
}
}
void ApplyGravity()
{
if(controller.isGrounded &&
velocity.y < 0)
{
velocity.y = -2f;
}
velocity.y +=
gravity *
Time.deltaTime;
controller.Move(
velocity *
Time.deltaTime);
}
void Crouch()
{
if(Input.GetKey(KeyCode.LeftControl))
{
crouching = true;
controller.height =
Mathf.Lerp(
controller.height,
crouchHeight,
Time.deltaTime *
crouchSmooth);
playerCamera.transform.localPosition =
Vector3.Lerp(
playerCamera.transform.localPosition,
new Vector3(
0,
cameraCrouchHeight,
0),
Time.deltaTime *
crouchSmooth);
}
else
{
crouching = false;
controller.height =
Mathf.Lerp(
controller.height,
standingHeight,
Time.deltaTime *
crouchSmooth);
playerCamera.transform.localPosition =
Vector3.Lerp(
playerCamera.transform.localPosition,
new Vector3(
0,
cameraStandHeight,
0),
Time.deltaTime *
crouchSmooth);
}
}
}
结束
方尖碑
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;
}
}
}
}
结束
能量球
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);
}
}
}
结束
能量球收集器
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);
}
}
结束
能量球生成
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);
}
}
}
结束
传送门
using UnityEngine;
public class Portal : MonoBehaviour
{
[Header("Linked Portal")]
public Portal linkedPortal;
[Header("Teleport Settings")]
public float teleportCooldown = 1f;
private bool canTeleport = true;
private void OnTriggerEnter(Collider other)
{
if (!canTeleport || linkedPortal == null)
return;
if (other.CompareTag("Player") || other.CompareTag("Enemy"))
{
Teleport(other);
}
}
void Teleport(Collider target)
{
canTeleport = false;
linkedPortal.canTeleport = false;
CharacterController controller = target.GetComponent<CharacterController>();
if (controller != null)
controller.enabled = false;
target.transform.position =
linkedPortal.transform.position +
linkedPortal.transform.forward * 2f;
target.transform.rotation =
linkedPortal.transform.rotation;
if (controller != null)
controller.enabled = true;
Invoke(nameof(ResetTeleport), teleportCooldown);
linkedPortal.Invoke(nameof(ResetTeleport), teleportCooldown);
}
void ResetTeleport()
{
canTeleport = true;
}
}
结束
传送门地形
using UnityEngine;
public class TerrainPortalSpawner : MonoBehaviour
{
[Header("Terrain")]
public Terrain terrain;
[Header("Portal Prefabs")]
public GameObject portalAPrefab;
public GameObject portalBPrefab;
[Header("Spawn Settings")]
public float spawnHeight = 2f;
[Header("Portal Amount")]
public int portalPairs = 3; // 生成多少对 A/B
[Header("Portal Distance")]
public float minPortalDistance = 50f;
public float maxPortalDistance = 300f;
[Header("Portal Life Cycle")]
public float portalLifetime = 120f;
public float respawnTime = 60f;
private GameObject[] portalA;
private GameObject[] portalB;
void Start()
{
SpawnPortals();
}
void SpawnPortals()
{
DestroyPortals();
portalA = new GameObject[portalPairs];
portalB = new GameObject[portalPairs];
for(int i = 0; i < portalPairs; i++)
{
Vector3 posA = GetRandomTerrainPosition();
Vector3 posB = GetDistancePosition(posA);
portalA[i] = Instantiate(
portalAPrefab,
posA,
Quaternion.identity
);
portalB[i] = Instantiate(
portalBPrefab,
posB,
Quaternion.identity
);
Portal a = portalA[i].GetComponent<Portal>();
Portal b = portalB[i].GetComponent<Portal>();
if(a != null && b != null)
{
a.linkedPortal = b;
b.linkedPortal = a;
}
}
Invoke(nameof(DecayPortals), portalLifetime);
}
Vector3 GetDistancePosition(Vector3 start)
{
Vector3 position;
int attempts = 0;
do
{
position = GetRandomTerrainPosition();
attempts++;
}
while(
Vector3.Distance(start, position) < minPortalDistance ||
Vector3.Distance(start, position) > maxPortalDistance
&& attempts < 100);
return position;
}
void DecayPortals()
{
DestroyPortals();
Invoke(nameof(SpawnPortals), respawnTime);
}
void DestroyPortals()
{
if(portalA != null)
{
foreach(GameObject p in portalA)
{
if(p != null)
Destroy(p);
}
}
if(portalB != null)
{
foreach(GameObject p in portalB)
{
if(p != null)
Destroy(p);
}
}
}
Vector3 GetRandomTerrainPosition()
{
Vector3 terrainPos = terrain.transform.position;
float x = Random.Range(
0,
terrain.terrainData.size.x
);
float z = Random.Range(
0,
terrain.terrainData.size.z
);
float y = terrain.SampleHeight(
new Vector3(
terrainPos.x + x,
0,
terrainPos.z + z
)
);
return new Vector3(
terrainPos.x + x,
y + spawnHeight,
terrainPos.z + z
);
}
}
结束
房间
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);
}
}
}
结束
房间出口
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();
}
}
结束
缩小
using UnityEngine;
using System.Collections.Generic;
public class SizeToggle : MonoBehaviour
{
[Header("Objects To Resize")]
public Transform player;
public List<Transform> troops = new List<Transform>();
[Header("Size Settings")]
public float normalSize = 1f;
public float shrunkenSize = 0.2f;
[Header("Toggle Key")]
public KeyCode toggleKey = KeyCode.T;
private bool isSmall = false;
void Start()
{
if (player == null)
player = transform;
}
void Update()
{
if (Input.GetKeyDown(toggleKey))
{
ToggleSize();
}
}
void ToggleSize()
{
isSmall = !isSmall;
float newSize = isSmall ? shrunkenSize : normalSize;
// 调整玩家大小
player.localScale = Vector3.one * newSize;
// 调整部队大小
foreach (Transform troop in troops)
{
if (troop != null)
{
troop.localScale = Vector3.one * newSize;
}
}
}
}
结束
地形雾
using UnityEngine;
public class TerrainFog : MonoBehaviour
{
[Header("Fog Settings")]
public bool enableFog = true;
public FogMode fogMode = FogMode.ExponentialSquared;
[Header("Fog Color")]
public Color fogColor = Color.gray;
[Header("Fog Density")]
[Range(0f, 0.1f)]
public float fogDensity = 0.02f;
[Header("Linear Fog Distance")]
public float startDistance = 50f;
public float endDistance = 300f;
void Start()
{
ApplyFog();
}
void Update()
{
ApplyFog();
}
void ApplyFog()
{
RenderSettings.fog = enableFog;
RenderSettings.fogMode = fogMode;
RenderSettings.fogColor = fogColor;
if (fogMode == FogMode.Exponential ||
fogMode == FogMode.ExponentialSquared)
{
RenderSettings.fogDensity = fogDensity;
}
else
{
RenderSettings.fogStartDistance = startDistance;
RenderSettings.fogEndDistance = endDistance;
}
}
}
结束
地形墙
using UnityEngine;
public class TerrainBoundarySpawner : MonoBehaviour
{
[Header("Terrain")]
public Terrain terrain;
[Header("Wall Settings")]
public float wallHeight = 50f;
public float wallThickness = 2f;
public Material wallMaterial;
void Start()
{
CreateWalls();
}
void CreateWalls()
{
if(terrain == null)
{
Debug.LogError(
"Terrain not assigned");
return;
}
TerrainData data =
terrain.terrainData;
Vector3 terrainPosition =
terrain.transform.position;
float width =
data.size.x;
float length =
data.size.z;
float height =
wallHeight;
// 北墙
CreateWall(
"North Wall",
new Vector3(
terrainPosition.x + width / 2,
height / 2,
terrainPosition.z + length
),
new Vector3(
width,
height,
wallThickness
)
);
// 南墙
CreateWall(
"South Wall",
new Vector3(
terrainPosition.x + width / 2,
height / 2,
terrainPosition.z
),
new Vector3(
width,
height,
wallThickness
)
);
// 东墙
CreateWall(
"East Wall",
new Vector3(
terrainPosition.x + width,
height / 2,
terrainPosition.z + length / 2
),
new Vector3(
wallThickness,
height,
length
)
);
// 西墙
CreateWall(
"West Wall",
new Vector3(
terrainPosition.x,
height / 2,
terrainPosition.z + length / 2
),
new Vector3(
wallThickness,
height,
length
)
);
}
void CreateWall(
string wallName,
Vector3 position,
Vector3 size)
{
GameObject wall =
GameObject.CreatePrimitive(
PrimitiveType.Cube);
wall.name =
wallName;
wall.transform.position =
position;
wall.transform.localScale =
size;
if(wallMaterial != null)
{
Renderer renderer =
wall.GetComponent<Renderer>();
renderer.material =
wallMaterial;
}
}
}
结束
时间影响
using UnityEngine;
public class TimeAffectedAI : MonoBehaviour
{
public float timeMultiplier = 1f;
public void SetTimeMultiplier(float value)
{
timeMultiplier = value;
}
public float GetTimeMultiplier()
{
return timeMultiplier;
}
}
结束
时间领域能力
using UnityEngine;
using System.Collections.Generic;
public class TimeZoneAbility : MonoBehaviour
{
[Header("Player or AI")]
public Transform owner;
[Header("Radius")]
public float radius = 30f;
[Header("Time Effects")]
public float slowTime = 0.3f;
public float fastTime = 2f;
private bool slowActive;
private bool fastActive;
void Update()
{
// Z = 减速时间
if (Input.GetKeyDown(KeyCode.Z))
{
slowActive = !slowActive;
fastActive = false;
}
// X = 加速时间
if (Input.GetKeyDown(KeyCode.X))
{
fastActive = !fastActive;
slowActive = false;
}
ApplyTime();
}
void ApplyTime()
{
if(owner == null)
return;
Collider[] targets = Physics.OverlapSphere(owner.position, radius);
foreach(Collider target in targets)
{
TimeAffectedAI timeAI = target.GetComponent<TimeAffectedAI>();
if(timeAI != null)
{
if(slowActive)
{
timeAI.SetTimeMultiplier(slowTime);
}
else if(fastActive)
{
timeAI.SetTimeMultiplier(fastTime);
}
else
{
timeAI.SetTimeMultiplier(1f);
}
}
}
}
void OnDrawGizmosSelected()
{
if(owner != null)
{
Gizmos.DrawWireSphere(owner.position, radius);
}
}
}
结束
商人 AI
using UnityEngine;
using UnityEngine.AI;
public class TraderAI : MonoBehaviour
{
[Header("AI Movement")]
public NavMeshAgent agent;
public float wanderRadius = 20f;
public float wanderTime = 5f;
[Header("Player")]
public Transform player;
public float tradeDistance = 3f;
[Header("Trading")]
public string traderName = "Merchant";
public int itemPrice = 10;
public int stock = 10;
[Header("Player Money")]
public int playerMoney = 100;
public int playerItems = 0;
private float timer;
private bool trading;
void Start()
{
timer = wanderTime;
}
void Update()
{
if (player == null) return;
float distance = Vector3.Distance(transform.position, player.position);
// 在玩家附近停下
if (distance <= tradeDistance)
{
agent.isStopped = true;
if (Input.GetKeyDown(KeyCode.E))
{
trading = !trading;
if (trading)
OpenTrade();
else
CloseTrade();
}
}
else
{
agent.isStopped = false;
Wander();
}
}
void Wander()
{
timer += Time.deltaTime;
if (timer >= wanderTime)
{
Vector3 randomDirection = Random.insideUnitSphere * wanderRadius;
randomDirection += transform.position;
NavMeshHit hit;
if (NavMesh.SamplePosition(randomDirection, out hit, wanderRadius, 1))
{
agent.SetDestination(hit.position);
}
timer = 0;
}
}
void OpenTrade()
{
Debug.Log(traderName + " opened shop");
Debug.Log("Press B to buy item for $" + itemPrice);
Debug.Log("Press S to sell item");
}
void CloseTrade()
{
Debug.Log("Trade closed");
}
void LateUpdate()
{
if (!trading)
return;
// 购买
if (Input.GetKeyDown(KeyCode.B))
{
Buy();
}
// 出售
if (Input.GetKeyDown(KeyCode.S))
{
Sell();
}
}
void Buy()
{
if(stock <= 0)
{
Debug.Log("Trader is out of stock");
return;
}
if(playerMoney >= itemPrice)
{
playerMoney -= itemPrice;
playerItems++;
stock--;
Debug.Log("Bought item!");
}
else
{
Debug.Log("Not enough money");
}
}
void Sell()
{
if(playerItems > 0)
{
playerItems--;
playerMoney += itemPrice;
Debug.Log("Sold item!");
}
else
{
Debug.Log("You have nothing to sell");
}
}
}
结束
部队 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);
}
}
}
结束
部队存储
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("Obelisk storage full");
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(
"Stored troop: "
+ troopObject.name
);
return;
}
}
Debug.Log("No troop nearby");
}
void ReleaseTroop()
{
if(storedTroops.Count == 0)
{
Debug.Log("No troops stored");
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(
"Released troop: "
+ troop.name
);
}
public int GetStoredTroopCount()
{
return storedTroops.Count;
}
void OnDrawGizmosSelected()
{
Gizmos.DrawWireSphere(
transform.position,
storageRange
);
}
}
结束
观察
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 =
正在加载版本记录…
正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。