├── .gitattributes
├── img
├── preview_1.png
├── preview_2.png
├── preview_3.png
└── codemap_white.png
├── .gitignore
├── Assets
└── MainStuff
│ └── Scripts
│ ├── FadeAudioSource.cs
│ ├── RotateObject.cs
│ ├── Settings.cs
│ ├── switchColor.cs
│ ├── MoveMenuShips.cs
│ ├── GrowAnimation.cs
│ ├── CamControl.cs
│ ├── Tower.cs
│ ├── Fighter.cs
│ ├── Building.cs
│ ├── RollerEnemyBase.cs
│ ├── MainMenu.cs
│ ├── FactionIndex.cs
│ ├── BombShell.cs
│ ├── RocketShell.cs
│ ├── Trooper.cs
│ ├── Seeker.cs
│ ├── GameMaster.cs
│ ├── Follower.cs
│ ├── Main.cs
│ ├── Ship.cs
│ ├── Weapon.cs
│ └── Player.cs
├── LICENSE
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/img/preview_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexfcoding/RTS-Sandbox/HEAD/img/preview_1.png
--------------------------------------------------------------------------------
/img/preview_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexfcoding/RTS-Sandbox/HEAD/img/preview_2.png
--------------------------------------------------------------------------------
/img/preview_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexfcoding/RTS-Sandbox/HEAD/img/preview_3.png
--------------------------------------------------------------------------------
/img/codemap_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexfcoding/RTS-Sandbox/HEAD/img/codemap_white.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Ignore everything in the root except the "Assets/MainStuff/Scripts" directory.
3 | /*
4 | !.gitignore
5 |
6 | !Assets/
7 | Assets/*
8 | !Assets/MainStuff/
9 | Assets/MainStuff/*
10 | !Assets/MainStuff/Scripts
11 | !img/
12 | *.meta
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/FadeAudioSource.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections;
3 |
4 | public static class FadeAudioSource {
5 |
6 | public static IEnumerator FadeOut (AudioSource audioSource, float FadeTime) {
7 | float startVolume = audioSource.volume;
8 |
9 | while (audioSource.volume > 0) {
10 | audioSource.volume -= startVolume * Time.deltaTime / FadeTime;
11 |
12 | yield return null;
13 | }
14 |
15 | audioSource.Stop ();
16 | audioSource.volume = startVolume;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/RotateObject.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class RotateObject : MonoBehaviour
6 | {
7 | float x, y, z;
8 | float speed;
9 | public Rigidbody RD;
10 | Vector3 m_EulerAngleVelocity;
11 | float time;
12 |
13 | private void Awake()
14 | {
15 | speed = 0.5f;
16 | y = Random.Range(-speed, speed);
17 | }
18 |
19 | private void Start()
20 | {
21 | m_EulerAngleVelocity = new Vector3(0, 10, 0);
22 | }
23 |
24 | void FixedUpdate()
25 | {
26 | transform.RotateAround(new Vector3(0, 0, 0), Vector3.up, 10 * Time.deltaTime);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/Settings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 | using UnityEngine.UI;
5 |
6 | [RequireComponent(typeof(AudioSource))]
7 |
8 | public class Settings : MonoBehaviour
9 | {
10 | public static Settings SET;
11 |
12 | ///
13 | /// Count of base ships (including player)
14 | ///
15 | public int mainBaseCount;
16 | public int startMoney;
17 | public int unitsCount;
18 | public int attackProbability;
19 | public bool aiPlayerBase;
20 |
21 | void Awake()
22 | {
23 | if (SET != null)
24 | GameObject.Destroy(SET);
25 | else
26 | SET = this;
27 |
28 | DontDestroyOnLoad(this);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/switchColor.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class switchColor : MonoBehaviour
6 | {
7 |
8 | public GameObject light;
9 | public bool triggered = true;
10 | int id;
11 |
12 | void Start()
13 | {
14 | id = gameObject.GetComponentInParent().factionId;
15 | InvokeRepeating("SwitchColor", 0f, 0.5f);
16 | }
17 |
18 | public void SwitchColor()
19 | {
20 | if (triggered)
21 | {
22 | light.gameObject.GetComponent().intensity = 10;
23 | light.gameObject.GetComponent().color = GameMaster.GM.fractionColors[id];
24 | triggered = false;
25 | }
26 | else
27 | {
28 | light.gameObject.GetComponent().intensity = 0;
29 | triggered = true;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/MoveMenuShips.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class MoveMenuShips : MonoBehaviour
6 | {
7 | float timerY;
8 | float timerX;
9 | float timerZ;
10 |
11 | void Start()
12 | {
13 | timerX = Random.Range(0, 100);
14 | timerY = Random.Range(0, 100);
15 | timerZ = Random.Range(0, 100);
16 | }
17 |
18 | void FixedUpdate()
19 | {
20 | timerX += Time.deltaTime;
21 | timerY += Time.deltaTime;
22 | timerZ += Time.deltaTime;
23 |
24 | gameObject.transform.position = new Vector3(gameObject.transform.position.x + Mathf.Sin(timerX) * 0.15f, gameObject.transform.position.y + Mathf.Sin(timerY) * 0.15f, gameObject.transform.position.z + Mathf.Sin(timerZ) * 0.15f);
25 | gameObject.transform.RotateAround(new Vector3(0, 0, 0), Vector3.up, 6 * Time.deltaTime);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/GrowAnimation.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class GrowAnimation : MonoBehaviour
6 | {
7 | public float tickBuilding;
8 | public float buildingHeightScale;
9 | public float buildSpeed;
10 |
11 | public void Start()
12 | {
13 | tickBuilding = 0.05f;
14 | InvokeRepeating("ConstructBuilding", 0f, 0.01f);
15 | }
16 |
17 | public void ConstructBuilding ()
18 | {
19 | if (tickBuilding < buildingHeightScale)
20 | {
21 | gameObject.transform.localScale = new Vector3(gameObject.transform.localScale.x, tickBuilding, gameObject.transform.localScale.z);
22 | tickBuilding += buildSpeed;
23 | }
24 | else if (tickBuilding > buildingHeightScale)
25 | {
26 | CancelInvoke("ConstructBuilding");
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/CamControl.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class CamControl : MonoBehaviour
6 | {
7 | public float rotationSpeed;
8 | float mouseX, mouseY;
9 | public Transform lookObject;
10 | public Transform player;
11 |
12 | void Start()
13 | {
14 | rotationSpeed = 0.8f;
15 | }
16 |
17 | void LateUpdate()
18 | {
19 | Control();
20 | }
21 |
22 | void Control ()
23 | {
24 | transform.LookAt(lookObject);
25 |
26 | mouseX += Input.GetAxis("Mouse X") * rotationSpeed;
27 | mouseY += Input.GetAxis("Mouse Y") * rotationSpeed * (-1);
28 | mouseY = Mathf.Clamp(mouseY, -60, 60);
29 |
30 | if (player.GetComponent().spectatorMode == false)
31 | if (player.GetComponent().stopCamControls == false)
32 | player.rotation = Quaternion.Euler(mouseY, mouseX - 70, 0);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Aleksander Fedotov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/Tower.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 |
6 | public class Tower : Seeker
7 | {
8 | public float healthBarTopPosition;
9 | public float levelTopPosition;
10 |
11 | public override void Awake()
12 | {
13 | level = 1;
14 | minDistance = 1000;
15 | minDistNum = 0;
16 | countOfItemsCollected = 0;
17 | alreadyHaveWeapon = true;
18 | dead = false;
19 | foundObject = false;
20 |
21 | textHP = Instantiate(GameMaster.GM.text3dDamage, transform.position + new Vector3(0, levelTopPosition, 0), Quaternion.Euler(0, 0, 0));
22 | textHP.gameObject.GetComponent().text = level.ToString();
23 | textHP.transform.parent = transform;
24 |
25 | healthBarScaleMultiplier = 0.3f;
26 | healthBar = Instantiate(GameMaster.GM.healthBar, transform.position + new Vector3(0, healthBarTopPosition, 0), Quaternion.Euler(0, 0, 0));
27 | healthBar.transform.SetParent(gameObject.transform);
28 | healthBar.transform.localScale = new Vector3(health / maxHP * healthBarScaleMultiplier, 0.02f, 1);
29 | }
30 |
31 | public void Start()
32 | {
33 |
34 | }
35 |
36 | public override void FindItemsAround(List objectList, List platformList)
37 | {
38 |
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/Fighter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class Fighter : Trooper
6 | {
7 | float randomY;
8 | Rigidbody rb;
9 |
10 | public void Start()
11 | {
12 | timer = Random.Range(0, 100);
13 | health = 800;
14 | maxHP = 800;
15 | rb = gameObject.GetComponent();
16 |
17 | randomCollisionStuckDirection = Random.Range(0, 2);
18 |
19 | if (randomCollisionStuckDirection == 0)
20 | randomCollisionStuckDirection = -1;
21 | if (randomCollisionStuckDirection == 1)
22 | randomCollisionStuckDirection = 1;
23 | }
24 |
25 | public override void Update()
26 | {
27 | FindItemsAround(GameMaster.GM.globalObjectList, GameMaster.GM.platformObjectList);
28 |
29 | if (dead == false)
30 | FlyAnimation();
31 | else
32 | rb.useGravity = true;
33 | }
34 |
35 | public void FlyAnimation ()
36 | {
37 | timer += Time.deltaTime;
38 |
39 | Vector3 moveSin = new Vector3(transform.position.x + Mathf.Sin(timer) * 0.1f,
40 | transform.position.y + Mathf.Sin(timer * 2f) * 0.1f,
41 | transform.position.z + Mathf.Sin(timer * 2f) * 0.1f);
42 |
43 | if (transform.position.y < 20)
44 | rb.AddForce(0, 300, 0, ForceMode.Impulse);
45 |
46 | rb.MovePosition(moveSin);
47 | }
48 |
49 | public override void OnCollisionStay(Collision collisioninfo)
50 | {
51 | if (collisioninfo.gameObject.GetComponent() != null || collisioninfo.gameObject.GetComponent() != null || collisioninfo.gameObject.GetComponent() != null)
52 | {
53 | gameObject.GetComponent().AddRelativeForce(new Vector3(100 * randomCollisionStuckDirection, 30, 0), ForceMode.Impulse);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/Building.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class Building : FactionIndex
6 | {
7 | public float tickBuilding;
8 | public float buildingHeightScale;
9 | public AudioSource beginConstruction;
10 | public AudioSource constructionComplete;
11 | public float buildSpeed;
12 | public Vector3 healthBarPosition;
13 |
14 | public override void Awake()
15 | {
16 | base.Awake();
17 | }
18 |
19 | public void Start()
20 | {
21 | health = 5000;
22 | maxHP = 5000;
23 | tickBuilding = 0.05f;
24 |
25 | if (beginConstruction != null && factionId == 0 && GameMaster.GM.aiPlayerBase == false)
26 | beginConstruction.Play();
27 |
28 | InvokeRepeating("ConstructBuilding", 0f, 0.05f);
29 |
30 | healthBarScaleMultiplier = 1;
31 | healthBar.transform.localScale = new Vector3(health / maxHP * healthBarScaleMultiplier, 0.05f, 1);
32 | healthBar.transform.localPosition = healthBarPosition;
33 | }
34 |
35 | public void FixedUpdate()
36 | {
37 | healthBar.transform.LookAt(Camera.main.transform.position);
38 | }
39 |
40 | public void ConstructBuilding()
41 | {
42 | if (tickBuilding < buildingHeightScale)
43 | {
44 | gameObject.transform.localScale = new Vector3(gameObject.transform.localScale.x, tickBuilding, gameObject.transform.localScale.z);
45 | tickBuilding += buildSpeed;
46 | }
47 | else if (tickBuilding > buildingHeightScale)
48 | {
49 | healthBar.transform.localPosition += new Vector3(0, 4, 0);
50 |
51 | if (factionId == 0 && GameMaster.GM.aiPlayerBase == false)
52 | constructionComplete.Play();
53 |
54 | CancelInvoke("ConstructBuilding");
55 | }
56 | }
57 |
58 | public void OnCollisionEnter(Collision collisioninfo)
59 | {
60 | if (collisioninfo.gameObject.tag == "Barracs")
61 | {
62 | gameObject.transform.position = GameMaster.GM.shipObjectList[factionId].transform.position + new Vector3(Random.Range(-100, 100), -GameMaster.GM.shipObjectList[factionId].transform.position.y, Random.Range(-100, 100));
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RTS-Sandbox
2 | C# Unity 3D classes for creation of action / real-time strategy games
3 |
4 | ## Game Example (Player vs AI vs AI)
5 |
6 | [](https://youtu.be/MSCK4LUibh0 "Game Example")
7 |
8 | ## 600 Units Battle (AI vs AI)
9 |
10 | [](https://youtu.be/4vnaKTg5Cvk "600 Units Test")
11 |
12 | ## Five Factions Battle (AI vs AI)
13 |
14 | [](https://youtu.be/AgjpS3nFU-U "Five Factions")
15 |
16 | ## Class Diagram
17 |
18 | 
19 |
20 | ## Features
21 | - Procedural creation of a randomized RTS battle with opposing factions interactions, simple economic system, building and resource mining
22 | - Two working modes:
23 | - Player vs AI
24 | - AI vs AI
25 | - All game logic code was created from scratch
26 | - Game example (videos above) uses free 3d-models, textures and some particle effects from Unity asset store
27 |
28 | ## Rules
29 |
30 | - "All against all" principle
31 | - A selected number of bases (Ship.cs) are placed on the map with physical resource objects (Follower.cs) at any place
32 | - Each faction has own unique color
33 | - AI opponents fight between their bases and the player (Player.cs)
34 | - Resource collector ships (Seeker.cs) of each faction ("factionId" in FactionIndex.cs) find resource objects and take to their bases
35 | - Resources change their colors to faction's color after the object picking up
36 | - AI builds defence towers and factories for units creation with collected resources
37 | - The player controls a small ship, attacks opponents and their bases
38 | - With a given probability, opponents send created units (Trooper.cs, Fighter.cs) to attack player's small ship and base
39 | - The player creates buildings (Building.cs), units, defence towers (Tower.cs), finds resources and takes to the base ship
40 | - The player groups units and gives them orders (follow the object, or attack the enemy)
41 | - Any unit, including the player, can pick up weapons: machine guns, rocket and bomb launchers (Weapon.cs)
42 | - Each unit has a level, which increases after destroying enemies
43 | - Resource is a physical rigidbody object that can be picked up as loot
44 | - All objects can be destroyable
45 |
46 | ## Usage
47 |
48 | - All needed prefabs are listed in GameMaster.cs
49 | - GameMaster.cs acts as a global static class that contains all prefab links for other classes
50 | - Add empty Game Object in Unity Hierarchy
51 | - Attach GameMaster.cs script to the object
52 | - Attach scripts for each prefab:
53 | - **Player:** Player.cs, PlayerController.cs, Main.cs
54 | - **Camera:** CamControl.cs
55 | - **Faction Base Ship:** Ship.cs
56 | - **Barracs and Factory:** Building.cs
57 | - **Gun-Tower, Rocket-Tower:** Tower.cs
58 | - **Trooper:** Trooper.cs
59 | - **LightShip:** Fighter.cs
60 | - **Resource Ship:** Seeker.cs
61 | - **Resource:** Follower.cs
62 | - **Machine Gun, Bomb Launcher, Rocket Launcher:** Weapon.cs
63 | - **Rocket:** RocketShell.cs
64 | - **Bomb:** BombShell.cs
65 | - Place player prefab with a Camera as a child on the map and connect all your other prefabs to GameMaster.cs
66 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/RollerEnemyBase.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 |
6 | public class RollerEnemyBase : Trooper
7 | {
8 | public override void Awake()
9 | {
10 | level = 1;
11 | attackTargetId = Random.Range(0, 6);
12 | targetIsShip = true;
13 | health = 2000;
14 | maxHP = 2000;
15 | destinationPass = false;
16 | foundTargetToAttack = false;
17 | wait = false;
18 | distToLerp = 170;
19 | gameObject.tag = "Trooper";
20 | gameObject.name = "Roller";
21 | wait = true;
22 | alreadyHaveWeapon = false;
23 | dead = false;
24 | foundObject = false;
25 | isVulnerable = true;
26 | textHP = Instantiate(GameMaster.GM.text3dDamage, transform.position + new Vector3(0, 10, 0), Quaternion.Euler(0, 0, 0));
27 | textHP.gameObject.GetComponent().text = level.ToString();
28 | textHP.transform.parent = transform;
29 | healthBarScaleMultiplier = 0.8f;
30 | pointFromShootingRandomize.Set(Random.Range(-40, 40), 0, Random.Range(-40, 40));
31 | }
32 |
33 | public override void Update()
34 | {
35 | FindItemsAround(GameMaster.GM.globalObjectList, GameMaster.GM.platformObjectList);
36 | }
37 |
38 | public override void FindItemsAround(List _GlobalObjectList, List _PlatformList)
39 | {
40 | if (dead == false && stopDoing == false)
41 | {
42 | if (targetToChase != null)
43 | {
44 | if (targetToChase.GetComponent() != null)
45 | {
46 | pointFromShooting = targetToChase.transform.position - new Vector3(0, targetToChase.transform.position.y, 0);
47 | }
48 | else
49 | {
50 | pointFromShooting = targetToChase.transform.position;
51 | }
52 | }
53 | else
54 | {
55 | int rnDShip = Random.Range(0, GameMaster.GM.mainBaseCount);
56 |
57 | while (rnDShip == factionId)
58 | rnDShip = Random.Range(0, GameMaster.GM.mainBaseCount);
59 |
60 | if (factionId != 0 && GameMaster.GM.shipObjectList[rnDShip] != null)
61 | targetToChase = GameMaster.GM.shipObjectList[rnDShip];
62 | else
63 | targetToChase = GameMaster.GM.player.gameObject;
64 | }
65 |
66 | if (targetToChase != null && targetToChase.GetComponent() != null)
67 | pointFromShooting = pointFromShooting + pointFromShootingRandomize * 4;
68 |
69 | if (targetToChase != null && targetToChase.GetComponent() == null)
70 | pointFromShooting = pointFromShooting + pointFromShootingRandomize;
71 |
72 | if ((currentWeapon != null && enemyToLook != null) || (currentWeapon != null && enemyToLook != null))
73 | {
74 | if (enemyToLook.GetComponent() != null)
75 | {
76 | wait = true;
77 | }
78 | else if (enemyToLook.GetComponent() == null)
79 | {
80 | wait = true;
81 | }
82 | }
83 | else
84 | {
85 | wait = false;
86 | }
87 |
88 | // если враг мертв, то двигаться дальше
89 | if (enemyToLook != null && enemyToLook.GetComponent() != null && enemyToLook.GetComponent().dead == true && currentWeapon.GetComponent().playerFollowingCommand == true)
90 | wait = false;
91 |
92 | if (((Vector3.Distance(transform.position, pointFromShooting)) > 80) && (wait == false))
93 | {
94 | Vector3 direction = (targetToChase.transform.position - transform.position).normalized;
95 | rbTrooper.AddForce(direction * 1, ForceMode.VelocityChange);
96 | }
97 | else
98 | {
99 | wait = true;
100 | }
101 |
102 | if (((Vector3.Distance(transform.position, pointFromShooting)) > 120))
103 | {
104 | wait = false;
105 | }
106 | }
107 |
108 | // Анимация смерти
109 | if (dead == true && stopDoing == false)
110 | {
111 | stopDoing = true;
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/MainMenu.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 | using UnityEngine.UI;
5 | using UnityEngine.SceneManagement;
6 | using TMPro;
7 |
8 | public class MainMenu : MonoBehaviour
9 | {
10 | public Slider factionsSlider;
11 | public Slider moneySlider;
12 | public Slider unitsSlider;
13 | public Slider probabilitySlider;
14 | public Toggle aiOnlyToggle;
15 |
16 | public TMP_Text factionCountText;
17 | public TMP_Text moneyCountText;
18 | public TMP_Text unitsCountText;
19 | public TMP_Text probabilityText;
20 |
21 | public GameObject factionShip;
22 |
23 | List shipsList;
24 | List factionColors;
25 |
26 | public void Start()
27 | {
28 | shipsList = new List();
29 | SetBaseCount();
30 | SetMoneyCount();
31 | SetUnitsCount();
32 | SetAttackProbability();
33 | SetMode();
34 | }
35 |
36 | public void PlayGame()
37 | {
38 | SceneManager.LoadScene(1, LoadSceneMode.Single);
39 | }
40 |
41 | public void QuitGame()
42 | {
43 | Application.Quit();
44 | }
45 |
46 | public void SetBaseCount()
47 | {
48 | gameObject.GetComponent().Play();
49 |
50 | int factionCount = (int)factionsSlider.value;
51 | Settings.SET.mainBaseCount = factionCount;
52 |
53 | factionCountText.GetComponent().text = $"Factions: {factionCount.ToString()}";
54 |
55 | float spawnCircleAngle = Random.Range(0, 360);
56 |
57 | if (shipsList != null)
58 | {
59 | for (int i = 0; i < shipsList.Count; i++)
60 | {
61 | Destroy(shipsList[i].gameObject);
62 | }
63 | }
64 |
65 | factionColors = new List();
66 |
67 | for (int i = 0; i < factionCount; i++)
68 | {
69 | float r, g, b;
70 |
71 | r = (float)(Random.Range(0, 255) / 255f);
72 | g = (float)(Random.Range(0, 255) / 255f);
73 | b = (float)(Random.Range(0, 255) / 255f);
74 |
75 | Color newRandomColor = new Color(r, g, b, 1f);
76 | factionColors.Add(newRandomColor);
77 | }
78 |
79 | factionColors[0] = new Color(0, 1, 1, 1f);
80 | factionColors[1] = new Color(1, 0, 1, 1f);
81 |
82 | for (int i = 0; i < factionCount; i++)
83 | {
84 | GameObject newShipObject = Instantiate(factionShip, new Vector3(200 * Mathf.Cos(spawnCircleAngle * 3.14f / 180), 0, 200 * Mathf.Sin(spawnCircleAngle * 3.14f / 180)), Quaternion.Euler(0, 0, 0));
85 | newShipObject.transform.LookAt(new Vector3(0, 0, 0));
86 | newShipObject.transform.localScale = new Vector3(0.045f, 0.045f, 0.045f);
87 |
88 | int lightsCount = 0;
89 |
90 | if (newShipObject.gameObject.GetComponentsInChildren() != null)
91 | {
92 | lightsCount = newShipObject.gameObject.GetComponentsInChildren().Length;
93 |
94 | for (int j = 0; j < lightsCount; j++)
95 | {
96 | newShipObject.gameObject.GetComponentsInChildren()[j].color = factionColors[i];
97 | }
98 | }
99 |
100 | shipsList.Add(newShipObject);
101 | spawnCircleAngle += 360 / Settings.SET.mainBaseCount;
102 | }
103 | }
104 |
105 | public void SetMoneyCount()
106 | {
107 | int startMoney = (int)moneySlider.value;
108 | Settings.SET.startMoney = startMoney;
109 | moneyCountText.GetComponent().text = $"Start Money: {startMoney.ToString()} %";
110 | }
111 |
112 | public void SetUnitsCount()
113 | {
114 | int maxUnits = (int)unitsSlider.value;
115 | Settings.SET.unitsCount = maxUnits;
116 | unitsCountText.GetComponent().text = $"Max Faction Units: {maxUnits.ToString()}";
117 | }
118 |
119 | public void SetAttackProbability()
120 | {
121 | int attackProbability = (int)probabilitySlider.value;
122 | Settings.SET.attackProbability = attackProbability;
123 | probabilityText.GetComponent().text = $"AI Attack Probability: {attackProbability.ToString()} %";
124 | }
125 |
126 | public void SetMode()
127 | {
128 | bool aiControlledPlayerBase = aiOnlyToggle.isOn;
129 | Settings.SET.aiPlayerBase = aiControlledPlayerBase;
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/FactionIndex.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class FactionIndex : MonoBehaviour
6 | {
7 | public int factionId;
8 |
9 | public bool isSimpleFollower;
10 | public bool dead, totallyDead;
11 | public bool isVulnerable;
12 | public bool lootAfterDeath;
13 |
14 | public float health;
15 | public float maxHP;
16 | public float healthBarScaleMultiplier;
17 | public float level;
18 |
19 | public GameObject healthBar;
20 | public GameObject whoIsDamaging;
21 | public GameObject deathEffect;
22 |
23 | public AudioSource deathSound;
24 |
25 | public float healthBarHeight;
26 | public float textHpHeight;
27 |
28 | public virtual void Awake()
29 | {
30 | level = 1;
31 | health = 150;
32 | maxHP = 150;
33 | healthBarScaleMultiplier = 0;
34 | healthBar = Instantiate(GameMaster.GM.healthBar, transform.position + new Vector3(0, healthBarHeight, 0), Quaternion.Euler(0, 0, 0));
35 | healthBar.transform.SetParent(gameObject.transform);
36 | healthBar.transform.localScale = new Vector3(health / maxHP * healthBarScaleMultiplier, 0.02f, 1);
37 | }
38 |
39 | public void SetFractionId(int fractionId)
40 | {
41 | this.factionId = fractionId;
42 |
43 | if (gameObject.name == "Seeker" || gameObject.name == "GunTower" || gameObject.name == "Tower")
44 | {
45 | int lightsCount = 0;
46 |
47 | if (gameObject.GetComponentsInChildren() != null)
48 | {
49 | lightsCount = gameObject.GetComponentsInChildren().Length;
50 |
51 | for (int i = 0; i < lightsCount; i++)
52 | {
53 | gameObject.GetComponentsInChildren()[i].color = GameMaster.GM.fractionColors[this.factionId];
54 | }
55 | }
56 | }
57 |
58 | if (healthBar != null)
59 | healthBar.GetComponent().color = GameMaster.GM.fractionColors[this.factionId];
60 | }
61 |
62 | public void SetHealth (float healthToSet)
63 | {
64 | health = healthToSet;
65 | maxHP = healthToSet;
66 | }
67 |
68 | public virtual void TakeDamage(float damage)
69 | {
70 | if (isVulnerable == true)
71 | {
72 | if (health > damage)
73 | {
74 | health -= damage;
75 | if (healthBar != null)
76 | healthBar.transform.localScale = new Vector3(health / maxHP * healthBarScaleMultiplier, 0.05f, 1);
77 | }
78 | else
79 | {
80 | if (dead == false)
81 | {
82 | if (healthBar != null)
83 | healthBar.transform.localScale = new Vector3(0, 0, 0);
84 |
85 | //DeathEffect = Instantiate(GameMaster.GM.SmokeAfterDeath, gameObject.transform.position, Quaternion.Euler(0, 0, 0));
86 | //DeathEffect.transform.parent = gameObject.transform;
87 |
88 | if (deathEffect != null)
89 | {
90 | GameObject deadBoom = Instantiate(deathEffect, gameObject.transform.position, Quaternion.Euler(0, 0, 0));
91 | Destroy(deadBoom, 5f);
92 | }
93 |
94 | if (deathSound != null)
95 | deathSound.Play();
96 |
97 | Collider[] colliders = Physics.OverlapSphere(gameObject.transform.position, 35);
98 |
99 | foreach (Collider hit in colliders)
100 | {
101 | if ((hit.GetComponent() != null && hit.GetComponent() == null && hit.GetComponent() == null) && (hit.name != "Rocket") && (hit.name != "Bomb"))
102 | hit.GetComponent().AddExplosionForce(700, gameObject.transform.position + new Vector3(0, 0, 0), 10, 1, ForceMode.Impulse);
103 | }
104 |
105 | if (lootAfterDeath == true)
106 | {
107 | for (int i = 0; i < 5; i++)
108 | {
109 | int RndNum = Random.Range(0, GameMaster.GM.detailsList.Count);
110 | GameObject createdObject = GameMaster.GM.ConstructObject(GameMaster.GM.detailsList[RndNum], transform.position + new Vector3(Random.Range(0, 4), Random.Range(0, 4), Random.Range(0, 4)), Quaternion.Euler(0, 0, 0), "Follower", GameMaster.GM.globalObjectList);
111 | if (createdObject.GetComponent() == null)
112 | createdObject.AddComponent();
113 | createdObject.GetComponent().mass = 5;
114 | if (createdObject.GetComponent() != null && createdObject.GetComponent().convex == false)
115 | createdObject.GetComponent().convex = true;
116 | }
117 | }
118 | }
119 |
120 | dead = true;
121 | health -= damage;
122 | GameMaster.GM.RecursiveDestroy(transform, gameObject, 5);
123 | }
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/BombShell.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class BombShell : RocketShell
6 | {
7 | bool exploded;
8 | public override void Awake()
9 | {
10 | isProjectile = true;
11 | playersBullet = false;
12 |
13 | if (gameObject.GetComponent() != null)
14 | {
15 | gameObject.GetComponent().AddRelativeForce(Random.Range(0, 200), Random.Range(0, 10), 1500, ForceMode.Impulse);
16 | gameObject.GetComponent().AddRelativeForce(0, 0, 0, ForceMode.Impulse);
17 | }
18 | }
19 | public override void MoveBullet()
20 | {
21 | Timer += Time.deltaTime;
22 |
23 | if (playersBullet == true && isHoming == true)
24 | if (Physics.BoxCast(GameMaster.GM.player.transform.TransformPoint(0, 0, 0), new Vector3(20, 20, 2), transform.forward, out RaycastHit hitInfo2, Quaternion.Euler(0, 0, 0), 400, 1 << 8))
25 | if ((hitInfo2.transform.tag == "Seeker" || hitInfo2.transform.tag == "Trooper") && (hitInfo2.transform.GetComponent().factionId != 0))
26 | {
27 | gameObject.transform.LookAt(hitInfo2.transform.position + new Vector3(0, 1, 0));
28 | Vector3 normalizeDirection = (hitInfo2.transform.position + new Vector3(0, 1, 0) - gameObject.transform.position).normalized;
29 | gameObject.transform.position += normalizeDirection * Time.deltaTime * 30;
30 | }
31 |
32 | if (Timer > 3 && exploded == false)
33 | {
34 | Explode();
35 | }
36 | }
37 |
38 | public override void OnCollisionEnter(Collision collision)
39 | {
40 | if (collision.gameObject != null && (collision.gameObject.name != "Bomb" && collision.gameObject.name != "Terrain" && collision.gameObject.GetComponent() !=null && weaponToStick != null && collision.gameObject.GetComponent() != weaponToStick.GetComponent().objectToStick.GetComponent()))
41 | if (playersBullet == false && collision.gameObject.tag == "Player" || playersBullet == true && collision.gameObject.tag != "Player" || playersBullet == false && collision.gameObject.tag != "Player")
42 | {
43 | Explode();
44 | }
45 | }
46 |
47 | public override void Explode()
48 | {
49 | audio2.Play();
50 |
51 | foreach (Transform child in gameObject.transform)
52 | {
53 | GameObject.Destroy(child.gameObject);
54 | }
55 |
56 | gameObject.transform.GetComponent().enabled = false;
57 | gameObject.transform.GetComponent().enabled = false;
58 |
59 | GameObject Explosions = Instantiate(explosionRocketPrefab, transform.position, Quaternion.Euler(0, 0, 0));
60 | Destroy(Explosions, 2f);
61 | Collider[] colliders = Physics.OverlapSphere(gameObject.transform.position, 50);
62 |
63 | foreach (Collider hit in colliders)
64 | {
65 | if ((hit.GetComponent() != null && hit.GetComponent() == null && hit.GetComponent() == null) && (hit.name != "Rocket"))
66 | hit.GetComponent().AddExplosionForce(800, gameObject.transform.position + new Vector3(0, 0, 0), 30, 1, ForceMode.Impulse);
67 |
68 | if (hit.GetComponent() != null && hit.gameObject != null)
69 | {
70 | if (weaponToStick != null && hit.transform.GetComponent().dead == false)
71 | hit.transform.GetComponent().whoIsDamaging = weaponToStick.GetComponent().objectToStick.gameObject;
72 |
73 | if (weaponToStick != null && weaponToStick.GetComponent().objectToStick.gameObject.name == "Player")
74 | {
75 | if (hit.transform.GetComponent().transform.tag != "Ship")
76 | hit.transform.GetComponent().TakeDamage(damage * 2f);
77 | else
78 | hit.transform.GetComponent().TakeDamage(damage / 10);
79 | }
80 | else if (weaponToStick != null)
81 | {
82 | if (hit.transform.GetComponent().transform.tag != "Ship")
83 | hit.transform.GetComponent().TakeDamage(damage);
84 | else
85 | hit.transform.GetComponent().TakeDamage(damage / 10);
86 | }
87 | }
88 |
89 | if (hit.GetComponent() != null)
90 | {
91 | hit.GetComponent().TakeDamage(damage);
92 | }
93 | }
94 |
95 | if (gameObject.GetComponent() != null)
96 | gameObject.GetComponent().enabled = false;
97 |
98 | if (gameObject.GetComponent() != null)
99 | gameObject.GetComponent().enabled = false;
100 |
101 | foreach (Transform child in transform)
102 | {
103 | if (child.GetComponent() != null)
104 | child.GetComponent().enabled = false;
105 | if (child.GetComponent() != null)
106 | child.GetComponent().enabled = false;
107 | }
108 |
109 | Destroy(gameObject, 3);
110 | exploded = true;
111 | }
112 | }
113 |
114 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/RocketShell.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using UnityEngine;
5 |
6 | public class RocketShell : MonoBehaviour
7 | {
8 | public GameObject weaponToStick;
9 | public GameObject explosionRocketPrefab;
10 |
11 | public AudioSource audio;
12 | public AudioSource audio2;
13 |
14 | public float speed;
15 | public float damage;
16 | public float dmgRadius;
17 | public float Timer;
18 |
19 | public bool isProjectile;
20 | public bool isHoming;
21 | public bool playersBullet;
22 |
23 | public Rigidbody rb;
24 |
25 | public void FixedUpdate()
26 | {
27 | MoveBullet();
28 | }
29 |
30 | public void LaunchSound()
31 | {
32 | audio.Play();
33 | }
34 |
35 | public virtual void MoveBullet ()
36 | {
37 | Timer += Time.deltaTime;
38 |
39 | if ((isProjectile==true) && (rb != null))
40 | rb.AddRelativeForce(0, 0, speed += 24, ForceMode.Acceleration);
41 |
42 | if (playersBullet == true && isHoming == true)
43 | if (Physics.BoxCast(GameMaster.GM.player.transform.TransformPoint(0, 0, 0), new Vector3(20, 20, 2), transform.forward, out RaycastHit hitInfo2, Quaternion.Euler(0, 0, 0), 400, 1 << 8))
44 | if ((hitInfo2.transform.tag == "Seeker" || hitInfo2.transform.tag == "Trooper")&&(hitInfo2.transform.GetComponent().factionId != 0))
45 | {
46 | gameObject.transform.LookAt(hitInfo2.transform.position + new Vector3(0, 1, 0));
47 | Vector3 normalizeDirection = (hitInfo2.transform.position + new Vector3(0, 1, 0) - gameObject.transform.position).normalized;
48 | gameObject.transform.position += normalizeDirection * Time.deltaTime * 30;
49 | }
50 |
51 | if (Timer > 5)
52 | Destroy(gameObject);
53 | }
54 |
55 | public virtual void Awake()
56 | {
57 | isProjectile = true;
58 | playersBullet = false;
59 | rb = gameObject.GetComponent();
60 | }
61 |
62 | public virtual void OnCollisionEnter(Collision collision)
63 | {
64 | if (collision.gameObject.name != "Rocket")
65 | if (playersBullet == false && collision.gameObject.tag=="Player" || playersBullet == true && collision.gameObject.tag != "Player" || playersBullet == false && collision.gameObject.tag != "Player")
66 | {
67 | ContactPoint contact = collision.contacts[0];
68 | Quaternion rot = Quaternion.FromToRotation(Vector3.up, contact.normal);
69 | Vector3 pos = contact.point;
70 |
71 | if (explosionRocketPrefab != null)
72 | {
73 | GameObject Explosions = Instantiate(explosionRocketPrefab, pos, Quaternion.Euler(0, 0, 0));
74 | Destroy(Explosions, 2f);
75 | }
76 |
77 | Explode();
78 | }
79 | }
80 |
81 | public virtual void Explode()
82 | {
83 | audio2.Play();
84 |
85 | foreach (Transform child in gameObject.transform)
86 | {
87 | GameObject.Destroy(child.gameObject);
88 | }
89 |
90 | Collider ammoCollider = gameObject.transform.GetComponent();
91 |
92 | ammoCollider.enabled = false;
93 | gameObject.transform.GetComponent().enabled = false;
94 |
95 | Collider[] colliders = Physics.OverlapSphere(gameObject.transform.position, 35);
96 |
97 | foreach (Collider hit in colliders)
98 | {
99 | FactionIndex fractionHitObject = hit.GetComponent();
100 |
101 | if ((hit.GetComponent() != null && hit.GetComponent() == null && hit.GetComponent() == null) && (hit.name != "Rocket") && (hit.name != "Bomb"))
102 | hit.GetComponent().AddExplosionForce(300, gameObject.transform.position + new Vector3(0, 0, 0), 20, 1, ForceMode.Impulse);
103 |
104 | if (fractionHitObject != null && hit.gameObject != null)
105 | {
106 | if (weaponToStick != null && fractionHitObject.dead == false)
107 | fractionHitObject.whoIsDamaging = weaponToStick.GetComponent().objectToStick.gameObject;
108 |
109 | if (weaponToStick != null && weaponToStick.GetComponent().objectToStick.gameObject.name == "Player")
110 | {
111 | if (fractionHitObject.transform.tag != "Ship")
112 | fractionHitObject.TakeDamage(damage * 2f);
113 | else
114 | fractionHitObject.TakeDamage(damage / 10);
115 |
116 | }
117 | else if (weaponToStick != null )
118 | {
119 | if(fractionHitObject.transform.tag != "Ship")
120 | fractionHitObject.TakeDamage(damage);
121 | else
122 | fractionHitObject.TakeDamage(damage / 10);
123 | }
124 | }
125 |
126 | if (hit.GetComponent() != null)
127 | {
128 | hit.GetComponent().TakeDamage(damage);
129 | }
130 | }
131 |
132 | if (gameObject.GetComponent() != null)
133 | gameObject.GetComponent().enabled = false;
134 |
135 | if (ammoCollider != null)
136 | ammoCollider.enabled = false;
137 |
138 | foreach (Transform child in transform)
139 | {
140 | if (child.GetComponent() != null)
141 | child.GetComponent().enabled = false;
142 | if (child.GetComponent() != null)
143 | child.GetComponent().enabled = false;
144 | }
145 |
146 | Destroy(gameObject, 3);
147 | }
148 | }
149 |
150 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/Trooper.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class Trooper : Seeker
6 | {
7 | public Vector3 pointFromShooting;
8 | public Vector3 pointFromShootingRandomize;
9 | public Vector3 pointToChase;
10 |
11 | public bool destinationPass;
12 | public bool wait;
13 | public bool foundTargetToAttack;
14 | public bool targetIsShip;
15 | public bool ignorePlayerCommandAndStay;
16 | public bool stopDoing;
17 | public bool rotateBody;
18 |
19 | public int attackTargetId;
20 | public int randomCollisionStuckDirection;
21 |
22 | public GameObject enemyToLook;
23 | public GameObject targetToChase;
24 | public GameObject targetToChaseByPlayerCommand;
25 | public GameObject teamSelectMark;
26 | public GameObject body;
27 |
28 | public float trooperSpeed;
29 | public float distToLerp;
30 | public float timer;
31 | float randomSpeedDeviation;
32 |
33 | public Rigidbody rbTrooper;
34 |
35 | public override void Awake()
36 | {
37 | level = 1;
38 | attackTargetId = Random.Range(0, 6);
39 | targetIsShip = true;
40 | health = 1500;
41 | maxHP = 1500;
42 | destinationPass = false;
43 | foundTargetToAttack = false;
44 | wait = false;
45 | distToLerp = 170;
46 | gameObject.tag = "Trooper";
47 | wait = true;
48 | alreadyHaveWeapon = false;
49 | dead = false;
50 | foundObject = false;
51 | isVulnerable = true;
52 |
53 | textHP = Instantiate(GameMaster.GM.text3dDamage, transform.position + new Vector3(0, textHpHeight, 0), Quaternion.Euler(0, 0, 0));
54 | textHP.gameObject.GetComponent().text = level.ToString();
55 | textHP.transform.parent = transform;
56 |
57 | healthBarScaleMultiplier = 0.8f;
58 | healthBar = Instantiate(GameMaster.GM.healthBar, transform.position + new Vector3(0, healthBarHeight, 0), Quaternion.Euler(0, 0, 0));
59 | healthBar.transform.localScale = new Vector3(health / maxHP * healthBarScaleMultiplier, 0.05f, 1);
60 | healthBar.transform.SetParent(gameObject.transform);
61 | pointFromShootingRandomize.Set(Random.Range(-40, 40), 0, Random.Range(-40, 40));
62 | }
63 |
64 | public void Start()
65 | {
66 | randomSpeedDeviation = (float) Random.Range(0, 1000) / 1000 / 8;
67 | trooperSpeed += randomSpeedDeviation;
68 |
69 | randomCollisionStuckDirection = Random.Range(0, 2);
70 |
71 | if (randomCollisionStuckDirection == 0)
72 | randomCollisionStuckDirection = -1;
73 | if (randomCollisionStuckDirection == 1)
74 | randomCollisionStuckDirection = 1;
75 |
76 | InvokeRepeating("KeepFormation", 0, 0.3f);
77 | }
78 |
79 | public override void Update()
80 | {
81 | FindItemsAround(GameMaster.GM.globalObjectList, GameMaster.GM.platformObjectList);
82 | }
83 |
84 | public override void FindItemsAround(List _GlobalObjectList, List _PlatformList)
85 | {
86 | if (dead == false && stopDoing == false)
87 | {
88 | if (targetToChase != null)
89 | {
90 | if (targetToChase.GetComponent() != null)
91 | {
92 | pointFromShooting = targetToChase.transform.position - new Vector3(0, targetToChase.transform.position.y, 0);
93 | }
94 | else
95 | {
96 | if (targetToChase.GetComponent() != null)
97 | {
98 | if (gameObject.name == "LightShip")
99 | pointFromShooting = new Vector3(targetToChase.transform.position.x, targetToChase.transform.position.y, targetToChase.transform.position.z);
100 | if (gameObject.name == "Trooper")
101 | pointFromShooting = new Vector3(targetToChase.transform.position.x, transform.position.y, targetToChase.transform.position.z);
102 | }
103 |
104 | if (targetToChase.GetComponent() != null)
105 | {
106 | if (gameObject.name == "LightShip")
107 | pointFromShooting = new Vector3(targetToChase.transform.position.x, targetToChase.transform.position.y, targetToChase.transform.position.z);
108 | if (gameObject.name == "Trooper")
109 | pointFromShooting = new Vector3(targetToChase.transform.position.x, transform.position.y, targetToChase.transform.position.z);
110 | }
111 | }
112 | }
113 | else
114 | {
115 | if (pointToChase != new Vector3(0, 0, 0))
116 | {
117 | pointFromShooting = pointToChase + pointFromShootingRandomize * 4;
118 | }
119 | else
120 | {
121 | if (factionId == 0 && GameMaster.GM.aiPlayerBase == false)
122 | {
123 | if (gameObject.name == "Trooper")
124 | pointFromShooting = new Vector3(GameMaster.GM.player.transform.position.x, transform.position.y, GameMaster.GM.player.transform.position.z) + pointFromShootingRandomize * 4;
125 | if (gameObject.name == "LightShip")
126 | pointFromShooting = new Vector3(GameMaster.GM.player.transform.position.x, GameMaster.GM.player.transform.position.y, GameMaster.GM.player.transform.position.z) + pointFromShootingRandomize * 4;
127 | }
128 | else
129 | {
130 | int rnDShip = Random.Range(0, GameMaster.GM.mainBaseCount);
131 |
132 | while (rnDShip == factionId)
133 | rnDShip = Random.Range(0, GameMaster.GM.mainBaseCount);
134 |
135 | if (GameMaster.GM.shipObjectList[rnDShip] != null)
136 | targetToChase = GameMaster.GM.shipObjectList[rnDShip];
137 |
138 | if (factionId != 0 && GameMaster.GM.aiPlayerBase == false && GameMaster.GM.shipObjectList[rnDShip] != null)
139 | targetToChase = GameMaster.GM.shipObjectList[rnDShip];
140 | }
141 | }
142 | }
143 |
144 | if (targetToChase != null && targetToChase.GetComponent() != null)
145 | pointFromShooting = pointFromShooting + pointFromShootingRandomize * 4;
146 |
147 | if (targetToChase != null && targetToChase.GetComponent() == null)
148 | pointFromShooting = pointFromShooting + pointFromShootingRandomize;
149 |
150 | if ((currentWeapon != null && enemyToLook != null) || (currentWeapon != null && enemyToLook != null) )
151 | {
152 | if (gameObject.name == "Trooper")
153 | {
154 | body.transform.LookAt(enemyToLook.transform.position);
155 |
156 | if (rotateBody)
157 | body.transform.eulerAngles = body.transform.eulerAngles + new Vector3(0, 0, -90);
158 |
159 | wait = true;
160 | }
161 | else
162 | {
163 | Quaternion lookOnLook = Quaternion.LookRotation(enemyToLook.transform.position - transform.position);
164 | transform.rotation = Quaternion.Slerp(transform.rotation, lookOnLook, Time.deltaTime * 4);
165 |
166 | if (rotateBody)
167 | body.transform.eulerAngles = body.transform.eulerAngles + new Vector3(0, 0, -90);
168 |
169 | wait = true;
170 | }
171 | }
172 | else
173 | {
174 | wait = false;
175 | }
176 |
177 | // если враг мертв, то двигаться дальше
178 | if (enemyToLook != null && enemyToLook.GetComponent() != null && enemyToLook.GetComponent().dead == true && currentWeapon.GetComponent().playerFollowingCommand == true)
179 | wait = false;
180 |
181 | if ( ((Vector3.Distance(transform.position, pointFromShooting)) > 80) && (wait == false) )
182 | {
183 | Quaternion lookOnLook = Quaternion.LookRotation(pointFromShooting - transform.position);
184 | transform.rotation = Quaternion.Slerp(transform.rotation, lookOnLook, Time.deltaTime * 4);
185 |
186 | rbTrooper.AddRelativeForce(Vector3.forward * trooperSpeed * Time.deltaTime * 40, ForceMode.VelocityChange);
187 |
188 | if (gameObject.GetComponent() != null)
189 | {
190 | gameObject.GetComponent().Play("Run_Guard");
191 | gameObject.GetComponent().speed = 1 + randomSpeedDeviation;
192 | }
193 | }
194 | else
195 | {
196 | wait = true;
197 |
198 | if (enemyToLook == false)
199 | {
200 | Quaternion lookOnLook = Quaternion.LookRotation(Vector3.forward - transform.position);
201 | transform.rotation = Quaternion.Slerp(transform.rotation, lookOnLook, Time.deltaTime * 4);
202 | }
203 |
204 | if (gameObject.GetComponent() != null)
205 | gameObject.GetComponent().Play("Idle");
206 | }
207 |
208 | if (((Vector3.Distance(transform.position, pointFromShooting)) > 120))
209 | {
210 | wait = false;
211 | }
212 | }
213 |
214 | // Анимация смерти
215 | if (dead == true && stopDoing == false)
216 | {
217 | if (gameObject.GetComponent() != null)
218 | gameObject.GetComponent().Play("Idle");
219 |
220 | stopDoing = true;
221 | }
222 | }
223 |
224 | public void KeepFormation()
225 | {
226 | if (wait == false)
227 | {
228 | Collider[] colliders = Physics.OverlapSphere(gameObject.transform.position, 100);
229 |
230 | foreach (Collider hit in colliders)
231 | {
232 | if ((hit.GetComponent() != null) && (hit.name != "Rocket") && hit.GetComponent() == null && hit.GetComponent() != null)
233 | {
234 | if (hit.name == "LightShip")
235 | hit.GetComponent().AddExplosionForce(70, gameObject.transform.position + new Vector3(0, 0, 0), 0, 1, ForceMode.Force);
236 | if (hit.name == "Trooper")
237 | hit.GetComponent().AddExplosionForce(800, gameObject.transform.position + new Vector3(0, 0, 0), 0, 1, ForceMode.Force);
238 | }
239 | }
240 | }
241 | }
242 |
243 | public virtual void OnCollisionStay(Collision collisioninfo)
244 | {
245 | if (collisioninfo.gameObject.GetComponent() != null || collisioninfo.gameObject.GetComponent() != null || collisioninfo.gameObject.GetComponent() != null)
246 | {
247 | rbTrooper.AddRelativeForce(Vector3.left * 300 * Random.Range(-1, 2), ForceMode.Impulse);
248 | }
249 | }
250 | }
251 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/Seeker.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class Seeker : FactionIndex
6 | {
7 | public float minDistance;
8 | public int minDistNum;
9 | public int countOfItemsCollected;
10 | public int lootMinCount;
11 |
12 | public Vector3 currentTarget;
13 |
14 | public bool foundObject;
15 | public bool findNextObject = true;
16 | public bool goingToBase;
17 | public bool alreadyHaveWeapon;
18 | public bool isStationary;
19 |
20 | public GameObject textHP;
21 | public GameObject smoke;
22 | public GameObject currentTargetObject;
23 | public Weapon currentWeapon;
24 |
25 | public float timer2;
26 |
27 | public override void Awake()
28 | {
29 | timer2 = Random.Range(0, 100);
30 | level = 1;
31 | gameObject.tag = "Seeker";
32 | minDistance = 1000;
33 | minDistNum = 0;
34 | countOfItemsCollected = 0;
35 | alreadyHaveWeapon = false;
36 | health = 100000;
37 | maxHP = 100000;
38 | dead = false;
39 | foundObject = false;
40 | isVulnerable = true;
41 |
42 | textHP = Instantiate(GameMaster.GM.text3dDamage, transform.position + new Vector3(0, textHpHeight, 0), Quaternion.Euler(0, 0, 0));
43 | textHP.gameObject.GetComponent().text = level.ToString();
44 | textHP.transform.parent = transform;
45 |
46 | healthBarScaleMultiplier = 10;
47 | healthBar = Instantiate(GameMaster.GM.healthBar, transform.position + new Vector3(0, healthBarHeight, 0), Quaternion.Euler(0, 0, 0));
48 | healthBar.transform.SetParent(gameObject.transform);
49 | healthBar.transform.localScale = new Vector3(health/maxHP * healthBarScaleMultiplier, 0.05f, 1);
50 | }
51 |
52 | public virtual void Update()
53 | {
54 | FindItemsAround(GameMaster.GM.globalObjectList, GameMaster.GM.platformObjectList);
55 | }
56 |
57 | public override void TakeDamage(float damage)
58 | {
59 | if (isVulnerable == true)
60 | {
61 | if (health > damage)
62 | {
63 | if (whoIsDamaging != null && whoIsDamaging.GetComponent().factionId != GetComponent().factionId)
64 | health -= damage;
65 |
66 | textHP.gameObject.GetComponent().text = level.ToString();
67 |
68 | if (healthBar != null)
69 | healthBar.transform.localScale = new Vector3(health / maxHP * healthBarScaleMultiplier, 0.02f, 1);
70 | }
71 | // Обездвижили
72 | else
73 | {
74 | if (dead == false)
75 | {
76 | if (healthBar != null)
77 | healthBar.transform.localScale = new Vector3(0, 0, 0);
78 |
79 | if (gameObject.GetComponent() == null && gameObject.GetComponent() != null)
80 | gameObject.GetComponent().AddForce(0, 800, 0, ForceMode.Impulse);
81 |
82 | StartCoroutine(Dying());
83 | }
84 |
85 | dead = true;
86 | health -= damage;
87 | }
88 | }
89 | }
90 |
91 | public void Heal(float healpoints)
92 | {
93 | health += healpoints;
94 | healthBar.transform.localScale = new Vector3(health / maxHP * healthBarScaleMultiplier, 0.05f, 1);
95 | }
96 |
97 | public void SetHealth(float inputHealth)
98 | {
99 | health = inputHealth;
100 | }
101 |
102 | public virtual void FindItemsAround(List objectList, List platformList)
103 | {
104 | RaycastHit GroundHit;
105 | Physics.Raycast(transform.position, -transform.up, out GroundHit, 10);
106 |
107 | transform.position = new Vector3(transform.position.x, 20, transform.position.z);
108 |
109 | healthBar.transform.LookAt(Camera.main.transform.position, -Vector3.up);
110 |
111 | if (objectList.Count > 0 && dead == false)
112 | {
113 | if (findNextObject == true)
114 | {
115 | minDistNum = Random.Range(0, objectList.Count);
116 | }
117 |
118 | if (objectList[minDistNum] == null || objectList[minDistNum].GetComponent().factionId != 0 && objectList[minDistNum].GetComponent().factionId != factionId || currentTargetObject.gameObject == null)
119 | {
120 | findNextObject = true;
121 | }
122 |
123 | if (objectList[minDistNum] != null)
124 | {
125 | if ((objectList[minDistNum].gameObject.tag == "Follower" && objectList[minDistNum].GetComponent().followOwner == false) || (goingToBase == false && objectList[minDistNum].gameObject.name == "Roller" && objectList[minDistNum].gameObject.GetComponent() != null))
126 | foundObject = true;
127 | else
128 | foundObject = false;
129 |
130 | if (objectList[minDistNum].gameObject.tag == "Follower" && findNextObject == false && objectList[minDistNum].GetComponent().followOwner == true)
131 | findNextObject = true;
132 |
133 | if (foundObject == true && goingToBase == false)
134 | {
135 | findNextObject = false;
136 |
137 | if(objectList[minDistNum].gameObject != null)
138 | {
139 | currentTarget = objectList[minDistNum].transform.position;
140 | currentTargetObject = objectList[minDistNum].gameObject;
141 | }
142 | else
143 | minDistNum = Random.Range(0, objectList.Count);
144 |
145 | Quaternion lookOnLook = Quaternion.LookRotation(new Vector3(currentTarget.x, transform.position.y, currentTarget.z) - transform.position);
146 | transform.rotation = Quaternion.Slerp(transform.rotation, lookOnLook, Time.deltaTime * 3f);
147 | Vector3 normalizeDirection = (objectList[minDistNum].gameObject.GetComponent().transform.position - gameObject.transform.position).normalized;
148 | gameObject.GetComponent().transform.position += normalizeDirection * Time.deltaTime * 70;
149 | }
150 | }
151 |
152 | if (goingToBase == true && platformList[factionId].gameObject != null)
153 | {
154 | currentTarget = new Vector3(platformList[factionId].transform.position.x, transform.position.y, platformList[factionId].transform.position.z);
155 |
156 | Quaternion lookOnLook = Quaternion.LookRotation(new Vector3(currentTarget.x, transform.position.y, currentTarget.z) - transform.position);
157 | transform.rotation = Quaternion.Slerp(transform.rotation, lookOnLook, Time.deltaTime * 3f);
158 | Vector3 normalizeDirection = (platformList[factionId].gameObject.GetComponent().transform.position - gameObject.transform.position).normalized;
159 | gameObject.GetComponent().transform.position += normalizeDirection * Time.deltaTime * 70;
160 | }
161 |
162 | if (countOfItemsCollected >= 8)
163 | goingToBase = true;
164 | else if (countOfItemsCollected == 0)
165 | goingToBase = false;
166 | else if (countOfItemsCollected != 0 && currentTargetObject == null)
167 | goingToBase = false;
168 |
169 | Collider[] colliders = Physics.OverlapSphere(gameObject.transform.position, 80, 1 << 9);
170 |
171 | foreach (Collider hit in colliders)
172 | if (gameObject.tag == "Seeker" && hit.tag == "Follower" && dead == false)
173 | {
174 | Vector3 normalizeDirection = (gameObject.transform.position - hit.transform.position).normalized;
175 | hit.transform.position += normalizeDirection * Time.deltaTime * hit.GetComponent().speed * 2;
176 | }
177 |
178 | if (findNextObject == false && foundObject == false)
179 | {
180 | findNextObject = true;
181 | }
182 | }
183 | }
184 |
185 | IEnumerator Dying()
186 | {
187 | yield return new WaitForSeconds(0f);
188 |
189 | if (whoIsDamaging != null)
190 | if (whoIsDamaging.GetComponent().level < 5)
191 | {
192 | whoIsDamaging.GetComponent().level += 1;
193 |
194 | if (whoIsDamaging.GetComponent() != null)
195 | whoIsDamaging.GetComponent().textHP.gameObject.GetComponent().text = level.ToString();
196 | }
197 |
198 | if (whoIsDamaging != null && (whoIsDamaging.tag == "Trooper" || whoIsDamaging.tag == "Seeker"))
199 | {
200 | whoIsDamaging.GetComponent().health += 1000;
201 | whoIsDamaging.GetComponent().maxHP += 1000;
202 | }
203 |
204 | if (whoIsDamaging != null && whoIsDamaging.tag == "Player")
205 | {
206 | whoIsDamaging.GetComponent().health += 200;
207 | whoIsDamaging.GetComponent().maxHP += 1000;
208 | GameMaster.GM.player.GetComponent().playerHealth3dText.text = $"HP: {GameMaster.GM.player.GetComponent().health}";
209 | }
210 |
211 | totallyDead = true;
212 |
213 | if (GetComponent() != null)
214 | GetComponent().Play();
215 |
216 | GameObject Explode = Instantiate(deathEffect, gameObject.transform.position, Quaternion.Euler(0, 0, 0));
217 |
218 | Destroy(Explode, 2f);
219 |
220 | if (lootAfterDeath == true && whoIsDamaging.gameObject!= null && whoIsDamaging.GetComponent() != null)
221 | {
222 | int rndLootCount = Random.Range(lootMinCount, lootMinCount + (int) gameObject.GetComponent().level);
223 |
224 | for (int i = 0; i < rndLootCount; i++)
225 | {
226 | int rndNum = Random.Range(0, GameMaster.GM.detailsList.Count);
227 |
228 | GameObject createdObject = GameMaster.GM.ConstructObject(GameMaster.GM.detailsList[rndNum], transform.position + new Vector3(Random.Range(-4, 4), Random.Range(0, 7), Random.Range(-4, 4)), Quaternion.Euler(0, 0, 0), "Follower", GameMaster.GM.globalObjectList);
229 |
230 | if (createdObject.GetComponent() == null)
231 | {
232 | createdObject.AddComponent();
233 | }
234 |
235 | createdObject.GetComponent().mass = 5;
236 | createdObject.GetComponent().useGravity = true;
237 | createdObject.GetComponent().angularDrag = 0.05f;
238 | createdObject.GetComponent().drag = 1f;
239 |
240 | if (createdObject.GetComponent() != null && createdObject.GetComponent().convex == false)
241 | createdObject.GetComponent().convex = true;
242 |
243 | createdObject.GetComponent().moveToNextOwner = true;
244 | }
245 | }
246 |
247 | Collider[] colliders = Physics.OverlapSphere(gameObject.transform.position, 50);
248 |
249 | foreach (Collider hit in colliders)
250 | {
251 | if ((hit.GetComponent() != null) && (hit.tag != "Rocket"))
252 | hit.GetComponent().AddExplosionForce(300, gameObject.transform.position, 100, Random.Range(0, 1), ForceMode.Impulse);
253 | }
254 |
255 | GameMaster.GM.RecursiveDestroy(transform, gameObject, 4);
256 | }
257 | }
258 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/GameMaster.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 | using UnityEngine.SceneManagement;
5 | using UnityEngine.UI;
6 |
7 | ///
8 | /// Class for global variables and functions
9 | ///
10 | /// \code
11 | /// sdfsdfsdfsd
12 | /// fsdfsdf
13 | /// sdf
14 | /// \endcode
15 | ///
16 | [RequireComponent(typeof(AudioSource))]
17 | public class GameMaster : MonoBehaviour
18 | {
19 | public static GameMaster GM;
20 |
21 | ///
22 | /// AI-based simulation without player
23 | ///
24 | public bool aiPlayerBase;
25 |
26 | ///
27 | /// Count of base ships (including player's)
28 | ///
29 | public int mainBaseCount;
30 | public int startMoney;
31 | public int unitsCount;
32 | public int attackProbability;
33 |
34 | public List fractionColors;
35 |
36 | ///
37 | /// Player health
38 | ///
39 | public Text playerHp;
40 |
41 | ///
42 | /// Player's main ship health
43 | ///
44 | public Text playerShipHp;
45 |
46 | ///
47 | /// Player money text
48 | ///
49 | public Text playerMoneyText;
50 |
51 | ///
52 | /// The enemy money text
53 | ///
54 | public Text enemyMoneyText;
55 |
56 | ///
57 | /// Small explosion effect
58 | ///
59 | public GameObject effectBoom;
60 |
61 | ///
62 | /// Effect for player and enemy death
63 | ///
64 | public GameObject enemyDestroy;
65 |
66 | ///
67 | /// Text with health above main bases
68 | ///
69 | public GameObject text3dDamage;
70 |
71 | ///
72 | /// Smoke after death
73 | ///
74 | public GameObject smokeAfterDeath;
75 |
76 | ///
77 | /// Main camera
78 | ///
79 | public GameObject myCamera;
80 |
81 | ///
82 | /// Spawn platform
83 | ///
84 | public GameObject spawnPlatform;
85 |
86 | ///
87 | /// Seeker prefab
88 | ///
89 | public GameObject seekerPrefab;
90 |
91 | ///
92 | /// Rocket launcher prefab
93 | ///
94 | public GameObject rocketLauncherPrefab;
95 |
96 | ///
97 | /// Rocket launcher mini prefab
98 | ///
99 | public GameObject rocketLauncherMiniPrefab;
100 |
101 | ///
102 | /// Bomb launcher prefab
103 | ///
104 | public GameObject bombLauncherPrefab;
105 |
106 | ///
107 | /// Machine gun prefab
108 | ///
109 | public GameObject machineGunPrefab;
110 |
111 | ///
112 | /// Trooper prefab
113 | ///
114 | public GameObject trooperPrefab;
115 |
116 | ///
117 | /// Trooper prefab
118 | ///
119 | public GameObject rollerEnemyBasePrefab;
120 |
121 | ///
122 | /// Tower prefab
123 | ///
124 | public GameObject TowerPrefab;
125 |
126 | ///
127 | /// Tower with gun prefab
128 | ///
129 | public GameObject TowerGunPrefab;
130 |
131 | ///
132 | /// FLight ship prefab
133 | ///
134 | public GameObject lightShipPrefab;
135 |
136 | ///
137 | /// Main ship base prefab
138 | ///
139 | public GameObject shipPrefab;
140 |
141 | ///
142 | /// Platform prefab for collecting resources
143 | ///
144 | public GameObject platformPrefab;
145 |
146 | ///
147 | /// Barracs prefab
148 | ///
149 | public GameObject trooperBase;
150 |
151 | ///
152 | /// Factory prefab
153 | ///
154 | public GameObject factoryPrefab;
155 |
156 | ///
157 | /// Healthbar above all units
158 | ///
159 | public GameObject healthBar;
160 |
161 | ///
162 | /// Team select sprite
163 | ///
164 | public GameObject teamSelect;
165 | public GameObject teamSelectSphere;
166 |
167 | ///
168 | /// Team marker sprite
169 | ///
170 | public GameObject teamMarker;
171 |
172 | ///
173 | /// Global object list
174 | ///
175 | public List globalObjectList;
176 |
177 | ///
178 | /// Rockets object list
179 | ///
180 | public List bulletObjectList;
181 |
182 | ///
183 | /// Weapon object list
184 | ///
185 | public List weaponObjectList;
186 |
187 | ///
188 | /// Main ship object list
189 | ///
190 | public List shipObjectList;
191 |
192 | ///
193 | /// Platform object list
194 | ///
195 | public List platformObjectList;
196 |
197 | ///
198 | /// Unit list
199 | ///
200 | public List unitList;
201 |
202 | ///
203 | /// Trooper barracs list
204 | ///
205 | public List trooperBaseList;
206 |
207 | ///
208 | /// Resources list (followers)
209 | ///
210 | public List detailsList;
211 |
212 | ///
213 | /// Player object
214 | ///
215 | public Transform player;
216 |
217 | ///
218 | /// To shake a camera
219 | ///
220 | public bool shakeCamera;
221 |
222 | ///
223 | /// Timer
224 | ///
225 | public float timer;
226 |
227 | ///
228 | /// Total number of cubes
229 | ///
230 | public int numCubes;
231 |
232 | ///
233 | /// Boom sound
234 | ///
235 | public AudioSource boomSound;
236 |
237 | ///
238 | /// Enemy explode sound
239 | ///
240 | public AudioClip explodeEnemySound;
241 |
242 | void Awake()
243 | {
244 | if (GM != null)
245 | GameObject.Destroy(GM);
246 | else
247 | GM = this;
248 |
249 | //DontDestroyOnLoad(this);
250 |
251 | if (Settings.SET != null)
252 | {
253 | mainBaseCount = Settings.SET.mainBaseCount;
254 | startMoney = Settings.SET.startMoney;
255 | unitsCount = Settings.SET.unitsCount;
256 | attackProbability = Settings.SET.attackProbability;
257 | aiPlayerBase = Settings.SET.aiPlayerBase;
258 | }
259 | else
260 | {
261 | mainBaseCount = 3;
262 | startMoney = 30;
263 | unitsCount = 100;
264 | attackProbability = 15;
265 | }
266 | }
267 |
268 | public void SetFactionColors ()
269 | {
270 | fractionColors = new List();
271 | List importantColors = new List();
272 |
273 | importantColors.Add(new Color(0, 1, 1, 1f));
274 | importantColors.Add(new Color(0, 1, 0.2f, 1f));
275 | importantColors.Add(new Color(1, 1, 0, 1f));
276 | importantColors.Add(new Color(1, 0, 0, 1f));
277 | importantColors.Add(new Color(1, 0, 1, 1f));
278 | importantColors.Add(new Color(1, 1, 1, 1f));
279 |
280 | for (int i = 0; i < GameMaster.GM.mainBaseCount; i++)
281 | {
282 | float r, g, b;
283 |
284 | r = (float)(Random.Range(0, 255) / 255f);
285 | g = (float)(Random.Range(0, 255) / 255f);
286 | b = (float)(Random.Range(0, 255) / 255f);
287 |
288 | Color newRandomColor = new Color(r, g, b, 1f);
289 | fractionColors.Add(newRandomColor);
290 | }
291 |
292 | for (int i = 0; i < fractionColors.Count; i++)
293 | {
294 | if (i <= 4)
295 | fractionColors[i] = importantColors[i];
296 | }
297 | }
298 |
299 | ///
300 | /// A custom constructor for objects
301 | ///
302 | /// The prefab.
303 | /// Random width range for spawning.
304 | /// Random length range for spawning.
305 | /// Spawning height.
306 | /// Quaternion.
307 | /// Name of the object.
308 | /// A list to add created object.
309 | ///
310 | public GameObject ConstructObject(GameObject prefab, float spawnWidth, float SpawnLength, float height, Quaternion Q, string objectName, List listToAdd)
311 | {
312 | Vector3 RandomSpawnPosition = new Vector3(Random.Range(spawnWidth, SpawnLength), height, Random.Range(spawnWidth, SpawnLength));
313 | GameObject CreatedObject = Instantiate(prefab, RandomSpawnPosition, Q) as GameObject;
314 | CreatedObject.gameObject.name = objectName;
315 | listToAdd.Add(CreatedObject);
316 | numCubes++;
317 | return CreatedObject;
318 | }
319 |
320 | ///
321 | /// ConstructObject method overload for fixed Vector3 SpawnPosition.
322 | ///
323 | public GameObject ConstructObject(GameObject prefab, Vector3 spawnPosition, Quaternion Q, string objectName, List listToAdd, bool renderMesh = true)
324 | {
325 | GameObject CreatedObject = Instantiate(prefab, spawnPosition, Q) as GameObject;
326 | CreatedObject.gameObject.name = objectName;
327 | listToAdd.Add(CreatedObject);
328 | numCubes++;
329 |
330 | if (CreatedObject.GetComponent() != null)
331 | CreatedObject.GetComponent().enabled = renderMesh;
332 |
333 | Component[] renderer;
334 |
335 | if(CreatedObject.GetComponentsInChildren() != null)
336 | {
337 | renderer = CreatedObject.GetComponentsInChildren();
338 |
339 | for (int i = 0; i < renderer.Length; i++)
340 | {
341 | if (renderer[i].gameObject.name == "Laser_Gun")
342 | renderer[i].GetComponent().enabled = renderMesh;
343 | }
344 | }
345 |
346 | return CreatedObject;
347 | }
348 |
349 | public void PlayEnemyExplosionSound(Vector3 position)
350 | {
351 | AudioSource.PlayClipAtPoint(explodeEnemySound, position);
352 | }
353 |
354 | ///
355 | /// Recursive destroying. Used for destroy all object childs.
356 | ///
357 | /// Object Transform to destroy.
358 | /// Game object to destroy.
359 | /// Time to destroy object.
360 | public void RecursiveDestroy (Transform objectTransform, GameObject gameObj, float timeToDestroy)
361 | {
362 | foreach (Transform child in objectTransform)
363 | {
364 | if (child.GetComponent() != null)
365 | child.GetComponent().enabled = false;
366 |
367 | if (child.GetComponent() != null)
368 | child.GetComponent().enabled = false;
369 |
370 | if (child.GetComponent() != null)
371 | child.GetComponent().enabled = false;
372 |
373 | if (child.GetComponent() != null)
374 | child.GetComponent().enabled = false;
375 |
376 | if (child.GetComponent() != null)
377 | child.GetComponent().Stop();
378 |
379 | RecursiveDestroy(child, gameObj, timeToDestroy);
380 | }
381 |
382 | if (gameObj.GetComponent() != null)
383 | gameObj.GetComponent().enabled = false;
384 |
385 | if (gameObj.GetComponent() == null)
386 | Destroy(gameObj, timeToDestroy);
387 | }
388 |
389 | ///
390 | /// Gives weapon to selected object.
391 | ///
392 | /// The object position.
393 | public void GiveWeaponToObject (Vector3 objectPosition)
394 | {
395 | int rnd = Random.Range(0, 100);
396 |
397 | if (rnd >= 65 && rnd < 100)
398 | GameMaster.GM.ConstructObject(GameMaster.GM.rocketLauncherMiniPrefab, objectPosition, Quaternion.Euler(0, 0, 0), "RocketLauncher", GameMaster.GM.weaponObjectList, false);
399 |
400 | if (rnd >= 30 && rnd < 65)
401 | GameMaster.GM.ConstructObject(GameMaster.GM.rocketLauncherPrefab, objectPosition, Quaternion.Euler(0, 0, 0), "RocketLauncher", GameMaster.GM.weaponObjectList, false);
402 |
403 | if (rnd <= 30)
404 | GameMaster.GM.ConstructObject(GameMaster.GM.machineGunPrefab, objectPosition, Quaternion.Euler(0, 0, 0), "MachineGun", GameMaster.GM.weaponObjectList, false);
405 | }
406 |
407 | public void FixedUpdate()
408 | {
409 | timer += Time.deltaTime;
410 | }
411 | }
412 |
--------------------------------------------------------------------------------
/Assets/MainStuff/Scripts/Follower.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | public class Follower : FactionIndex
6 | {
7 | public float speed;
8 | public float jumpPower;
9 | public bool followOwner;
10 | public bool followOwnerCharger;
11 | public bool jumping;
12 | public bool moveToNextOwner;
13 | public GameObject pickUpEffect;
14 | public GameObject ownerToFollow;
15 | public GameObject chargerToFollow;
16 | public AudioSource audioPickEnemyCube;
17 | public AudioSource audioPickCubeToMe;
18 | public AudioSource audioPickShipCube;
19 | int rndDestroyTime;
20 |
21 | public override void Awake()
22 | {
23 | rndDestroyTime = Random.Range(0, 20);
24 | health = 50;
25 | maxHP = 50;
26 | gameObject.tag = "Follower";
27 | jumpPower = 15;
28 | speed = 50;
29 | followOwner = false;
30 | factionId = 10;
31 | followOwnerCharger = false;
32 | jumping = true;
33 | isSimpleFollower = true;
34 | isVulnerable = false;
35 | }
36 |
37 | public void FixedUpdate()
38 | {
39 | MoveTo();
40 | InvokeRepeating("CheckForDestroy", 10f + rndDestroyTime, 1f);
41 | }
42 |
43 | public virtual void MoveTo()
44 | {
45 | if (followOwner == true) // Если двигаться к владельцу (определяется в Collision ниже)
46 | {
47 | Vector3 normalizeDirection; // Направление движения
48 | float xpos = gameObject.GetComponent().transform.position.x;
49 | float zpos = gameObject.GetComponent().transform.position.z;
50 |
51 | if (ownerToFollow != null)
52 | {
53 | if (ownerToFollow.GetComponent() != null) // Если владелец куба - игрок ...
54 | normalizeDirection = (ownerToFollow.transform.TransformPoint(0, 0, -12000) - gameObject.GetComponent().transform.position + new Vector3(0, 3, 0)).normalized; // ... то двигаться к точке позади игрока
55 | else // Если владелец куба - не игрок ...
56 | normalizeDirection = (ownerToFollow.transform.TransformPoint(0, 5, -100) - gameObject.GetComponent().transform.position + new Vector3(0, 3, 0)).normalized; // ... то двигаться к точке позади владельца
57 |
58 | if (ownerToFollow.gameObject.tag == "Seeker")
59 | transform.position += normalizeDirection * Time.deltaTime * speed * 1.5f; // Сближать координату куба с Seeker или Player (перемещать куб)
60 |
61 | if (ownerToFollow.gameObject.tag == "Player")
62 | transform.position += normalizeDirection * Time.deltaTime * speed * 2f; // Сближать координату куба с Seeker или Player (перемещать куб)
63 |
64 | if (ownerToFollow.gameObject.tag != "Player" && ownerToFollow.gameObject.tag != "Seeker")
65 | transform.position += normalizeDirection * Time.deltaTime * speed * 1f; // Сближать координату куба с Seeker или Player (перемещать куб)
66 | }
67 |
68 | if (ownerToFollow != null)
69 | if (ownerToFollow.GetComponent() != null) // Если владелец - Seeker ...
70 | if (ownerToFollow.GetComponent().totallyDead == true) // ... и он мертв ...
71 | {
72 | if (gameObject.GetComponentsInChildren() != null)
73 | {
74 | int lightsCount = gameObject.GetComponentsInChildren().Length;
75 |
76 | for (int i = 0; i < lightsCount; i++)
77 | {
78 | //gameObject.GetComponentsInChildren()[i].color = Color.white;
79 | }
80 | }
81 |
82 | if (ownerToFollow.GetComponent().whoIsDamaging!=null)
83 | {
84 | ownerToFollow = ownerToFollow.GetComponent().whoIsDamaging;
85 | factionId = 10; // Установить идентификатор FractionId
86 | moveToNextOwner = true;
87 | StartCoroutine(MoveToNextOwnerTrigger());
88 | gameObject.tag = "Follower"; // вернуть тэг кубу Follower
89 | }
90 | else
91 | {
92 | followOwner = false; // убрать владельца
93 | gameObject.tag = "Follower"; // вернуть тэг кубу Follower
94 | factionId = 10;
95 | }
96 | }
97 |
98 | for (int i = 0; i < GameMaster.GM.platformObjectList.Count; i++) // Цикл по всем платформам
99 | {
100 | if (GameMaster.GM.platformObjectList[i] != null)
101 | if ((xpos > GameMaster.GM.platformObjectList[i].transform.position.x - GameMaster.GM.platformObjectList[i].transform.lossyScale.x / 2) && (xpos < GameMaster.GM.platformObjectList[i].transform.position.x + GameMaster.GM.platformObjectList[i].transform.lossyScale.x / 2) &&
102 | (zpos > GameMaster.GM.platformObjectList[i].transform.position.z - GameMaster.GM.platformObjectList[i].transform.lossyScale.z / 2) && (zpos < GameMaster.GM.platformObjectList[i].transform.position.z + GameMaster.GM.platformObjectList[i].transform.lossyScale.z / 2)) // Если куб над или под платформой i ...
103 | {
104 | chargerToFollow = GameMaster.GM.platformObjectList[i]; // ... то установить платформу к которой двигаться ChargerToFollow
105 |
106 | followOwnerCharger = true; // Если над или под платформой, то команда двигаться к платформе = true ...
107 | followOwner = false; // ... и перестать следовать за владельцем
108 | }
109 | }
110 |
111 | if (moveToNextOwner == true)
112 | {
113 | MoveAfterOwnerDeath();
114 | }
115 | }
116 |
117 | if (followOwnerCharger == true && chargerToFollow.gameObject != null) // Если двигаться к платформе
118 | {
119 | Vector3 normalizeDirection = (chargerToFollow.transform.position - gameObject.GetComponent().transform.position + new Vector3(0, 8, 0)).normalized; // ... то определить направление и ...
120 | gameObject.GetComponent().transform.position += normalizeDirection * Time.deltaTime * speed * 2; // ... сближаться с платформой
121 | gameObject.GetComponent().AddForce(0, 1000, 0); // Подталкивать куб вверх для столкновения с Ship
122 | }
123 | }
124 |
125 | public void JumpAnimation()
126 | {
127 | if (gameObject.GetComponent() != null && jumping == true)
128 | {
129 | gameObject.GetComponent().GetComponent().AddForce(0, Random.Range(-jumpPower, jumpPower), 0, ForceMode.Impulse);
130 | gameObject.GetComponent().GetComponent().AddForce(Random.Range(-jumpPower, jumpPower / 10), 0, 0, ForceMode.Impulse);
131 | gameObject.GetComponent().GetComponent().AddForce(0, 0, Random.Range(-jumpPower, jumpPower), ForceMode.Impulse);
132 | }
133 | }
134 |
135 | public void MoveAfterOwnerDeath ()
136 | {
137 | speed = 60;
138 |
139 | gameObject.GetComponent().mass = 5;
140 | gameObject.GetComponent().angularDrag = 1;
141 | //gameObject.GetComponent().useGravity = false;
142 | Vector3 normalizeDirection;
143 |
144 | if (ownerToFollow != null)
145 | {
146 | normalizeDirection = (ownerToFollow.transform.position - gameObject.GetComponent().transform.position).normalized; ; // движемся к тому, кто убил владельца
147 | gameObject.GetComponent().transform.position += normalizeDirection * Time.deltaTime * speed; // ... сближаться с новым владельцем
148 | }
149 | }
150 |
151 | IEnumerator MoveToNextOwnerTrigger()
152 | {
153 | //yield return new WaitForSeconds(0.8f);
154 | yield return new WaitForSeconds(0);
155 | moveToNextOwner = false;
156 | speed = 50;
157 | //gameObject.GetComponent().useGravity = true;
158 | gameObject.GetComponent().mass = 5;
159 |
160 | if (factionId == 10)
161 | followOwner = false;
162 | }
163 |
164 | public void CheckForDestroy()
165 | {
166 | if (ownerToFollow == null)
167 | {
168 | Destroy(gameObject);
169 | }
170 | }
171 |
172 | public virtual void OnCollisionEnter(Collision collisioninfo)
173 | {
174 | if (collisioninfo.gameObject.tag == "Terrain" && jumping == true)
175 | {
176 | gameObject.GetComponent().GetComponent().AddForce(0, Random.Range(4, jumpPower * 6), 0, ForceMode.Impulse);
177 | gameObject.GetComponent().GetComponent().AddForce(Random.Range(-jumpPower, jumpPower), 0, 0, ForceMode.Impulse);
178 | gameObject.GetComponent().GetComponent().AddForce(0, 0, Random.Range(-jumpPower, jumpPower), ForceMode.Impulse);
179 | }
180 |
181 | if (collisioninfo.gameObject.tag == "Seeker") // Если куб столкнулся с Seeker или Player ...
182 | {
183 | if (gameObject.GetComponent().factionId == 10) // ... и его индекс равен 10 (свободный)
184 | {
185 | gameObject.GetComponent().SetFractionId(collisioninfo.gameObject.GetComponent().factionId); // установить индекс равный Seeker или Player
186 |
187 | if (collisioninfo.gameObject.GetComponent() != null) // Если столкновение с Seeker, то ...
188 | {
189 | Seeker Seeker = collisioninfo.gameObject.GetComponent();
190 | Seeker.findNextObject = true; // Команда Seeker для поиска нового куба
191 | Seeker.countOfItemsCollected++; // Счетчик подобранных кубов++
192 | }
193 |
194 | // if (collisioninfo.gameObject.GetComponent() != null) // Если столкновение с Player, то ...
195 | // collisioninfo.gameObject.GetComponent().Heal(20); // Лечение Player
196 |
197 | ownerToFollow = collisioninfo.collider.gameObject; // Присвоить кубу владельца OwnerToFollow (Seeker или Player)
198 |
199 | if (gameObject.GetComponentsInChildren() != null)
200 | {
201 | int lightsCount = gameObject.GetComponentsInChildren().Length;
202 |
203 | for (int i = 0; i < lightsCount; i++)
204 | {
205 | gameObject.GetComponentsInChildren()[i].color = GameMaster.GM.fractionColors[this.factionId];
206 | }
207 | }
208 |
209 | gameObject.GetComponent