War Champions War Champions Final Year Project -II Project Report By: Sarah Fatima, Syed Faraz Ahmed & Varda Sarfraz Supervisor: Dr Sajjad Haider FCS IBA Page 1 War Champions Table of Contents Table of Figures ............................................................................................................................................. 3 Introduction: ................................................................................................................................................. 3 ENVIRNOMENT # 1.................................................................................................................................... 4 ENVIRNOMENT # 2.................................................................................................................................... 5 High Level Design: ......................................................................................................................................... 6 Rationale and sources of your project idea .............................................................................................. 7 Logical structure:....................................................................................................................................... 7 Background ............................................................................................................................................... 8 Hardware / Software tradeoffs ................................................................................................................. 9 Resources: ............................................................................................................................................... 10 Patents, copyright and trademarks......................................................................................................... 10 Software / Hardware Design: ...................................................................................................................... 11 Program Details....................................................................................................................................... 11 Overview ............................................................................................................................................. 11 User interface.................................................................................................................................... 14 ............................................................................................................................................................ 17 Errors.................................................................................................................................................. 18 Trails and tests ................................................................................................................................. 18 Hardware Details .................................................................................................................................... 19 Results: ........................................................................................................................................................ 20 Conclusions: ................................................................................................................................................ 20 Appendix: .................................................................................................................................................... 21 Appendix 1: Code .................................................................................................................................... 21 Appendix 4: Software/parts list ............................................................................................................ 142 Appendix 5: Work distribution.............................................................................................................. 143 FOR FYP-1 .......................................................................................................................................... 143 FOR FYP-2 .......................................................................................................................................... 143 Appendix 6: Project timeline ................................................................................................................ 144 For FYP-1 ........................................................................................................................................... 144 FOR FYP-II .......................................................................................................................................... 144 References: ............................................................................................................................................... 145 FCS IBA Page 2 War Champions Inspirations for code and designs: .................................................................................................... 145 Papers: .............................................................................................................................................. 145 Background sites: .............................................................................................................................. 145 Acknowledgements:.................................................................................................................................. 145 Table of Figures Figure 1 Environment 1 ................................................................................................................................. 4 Figure 2-Environment 1 ................................................................................................................................ 5 Figure 3- Environment 2 ............................................................................................................................... 5 Figure 4- Environment 2 ............................................................................................................................... 6 .Figure 5 – System Level Overview ....................................................................................................... 12 Figure 6- PLAYER 1’S TERRITORY ................................................................................................................. 14 Figure 7- PLAYER 2’S TERRITORY ................................................................................................................. 15 Figure 8– UNITS COMING OUT OF BUILDINGS ........................................................................................... 15 Figure 9-PLAYER 1 AND PLAYER 2 ATTACKING EACHOTHER ...................................................................... 16 Figure 10-PLAYER 1 CONQUERING PLAYER 2’S TERRITORY BY CAPURTING PLAYER 2’S HEADQUARTER AND DEFEATING PLAYER 2’S ARMY.. .......................................................................................................... 16 Introduction: FCS IBA Page 3 War Champions “War champions” is a multiplayer strategy game. The aim of the game War Champions is to build your own territory, army and units. You must protect your own castle from your opponent and try to conquer their castle to extend your territory .Player wins by successfully conquering the other players’ castle. War Champions is targeting on casual gamers who are looking for the ultimate immersed control experience, sense of speed and wonderful graphics. It is a smartphone multi-platform based game covering Android, Windows and iOS. The flexibility, portability and strong interaction with gamers make it attractive to widest possible audience. Multi-player feature is also included to make the game more interesting and interactive for the gamers. Our target market is teenage group and plus audience. The game tests different cognitive skills of the user’s brain. It will consist of obstacles that test the user’s ability to make rational decision in the nick of time. We have provided a seamless user interface that will allow the user to get fully immersed in the game. The main platform for the development of the game is “UNITY 3D” and coding was done in C#. We have also used a bit of “Blender”, “Photoshop”, “3Dx Max” and illustrator for the designing, development and rendering of the 3D models. War champions – Battle forces is designed as an online multiplayer game. It supports multiplatform functionality, specifically focusing on Android, Windows, and iOS. It has an Isometric view. War Champions is a 3-Dimensional, real-time strategy based game. The revenue would be generated through downloads on Playstore and AppStore. Options of various units each with unique abilities to conquer the enemy’s castle are present in the game. There are two immersive environments for each level.Initially the game is free to download and play. After a month of its publishing on App and PlayStore it will be downloaded on a certain fixed price. This will also help in generating revenue. The ideas were implemented both technically and artistically. We optimized the algorithm to capture the users’ movements to make sure the control is precise and sensitive. Graphics effects were also be carefully designed, and tested to ensure the most vivid and convenient feeling to the users. ENVIRNOMENT # 1 Figure 1 Environment 1 FCS IBA Page 4 War Champions Figure 2-Environment 1 ENVIRNOMENT # 2 Figure 3- Environment 2 FCS IBA Page 5 War Champions Figure 4- Environment 2 High Level Design: FCS IBA Page 6 War Champions Rationale and sources of your project idea Set to grow at 10 percent per annum over the next two years, the global animation and gaming industry offered tremendous opportunities to students in conceptualizing and creating animation to make a name for the country in creative areas, The gaming industry is set to grow at a rate of 1 percent per annum in the time period of next two years. There are various remarkable opportunities for students in creating games, creating and conceptualizing animation as per the global animation and gaming industry. It’s also expected that the gaming industry will touch revenue of $170 billion over the next two years and as an outcome of this the animation and gaming sector is expected The industry is expected to touch $170 billion in the next two years and "as a result, Indian animation and gaming sector, deriving revenue from international production houses and game development companies, is on the cusp of significant growth". Mobile gaming industry is on boom these days as said by Tim Merel, Digi-Capital --- As smartphone penetration increases, the possibilities become endless “Mobile Games will generate more revenue than console titles in 2015” –Newzoo----- Mobile cheaper to buy than consoles; hence more mobile gaming market. Games in mobile are expected to will produce much more revenue as compare to Console games in this current year i.e. 2015 according to Research specialist working for NewZoo “In its quarterly global games market update, the company estimates that revenues from smartphone and tablet titles will reach $25bn in 2014, up 42% on 2013, and $30.3bn in 2015. The company sees steady growth in the mature US and European regions, but much more explosive expansion in the emerging south-east Asian markets and China up by 86%.” NewZoo also predicts strong growth in Japanese iOS and Android game revenues, offsetting the decline of the region’s previously dominant feature phones. Logical structure: FCS IBA Page 7 War Champions The structure of our game is quite complex and comprehensive; a simplified version of it is being presented here. 7. Both Players Perform Actions. 1. Press Connect to connect to the master server. 2. From the master server we are automatically connected to the main lobby in the server. 8. Actions are communicated to master client (Which now acts as server) 3. Create room to create a game; the Person to create the room is now the master client. 9. The Master Client verifies the results of the Actions (Inputs), this is done to prevent cheating and have a deterministic simulation. 4. Wait for other player to joining game. 10. The results are communicated to the rest of the clients. 5. Opponent Joined. 6. Initialize Startup scripts, Assign Teams. (Loop Below Boxes) 11. Logical progression of the game based on the actions is simulated. 12. The Game is rendered based on the current logical state. Background Gaming Industry is booming globally. It’s a lucrative as well as entertaining business. And in the near future its progress graph will drastically shoot up. “Mobile gaming to push industry above $100 billion by 2017” -Digi-Capital's Tim Merel says much of this growth will come from Asian markets FCS IBA Page 8 War Champions The research firm says that mobile and online gaming is becoming such a huge force worldwide that it could grow at a compound annual growth rate of 23.6 percent, ultimately accounting for about 60 percent of software market share in 2017 while generating $60 billion of the predicted $100 billion for the overall industry. Main Market is Asia. With 48% of the global revenue, the Asia-Pacific region is by far the biggest market for mobile games. "Asia is becoming the biggest growth driver of economic value in mobile/online games, with the best games companies' revenue growth and profit margins being the envy of foreign competitors," said Tim Merel, managing director at Digi-Capital. Game Industry in Pakistan The mobile games and entertainment apps industry has a huge customer base and this high demand has helped Pakistan gain immense visibility in this sphere of software development. While companies like Pepper.pk topped BlackBerry’s Appworld with their game Ninja Fruit Bash, TenPearls won Nokia and AT&T Innovators 2011 contest through their game Animal 101, start-ups such as PiLabs also made their mark with mobile games such as ‘Field Garfield’ which is an official Garfield game. Another motivation for choosing this project as a FYP was that, we wanted to develop something that was interesting technically challenging, something that wasn’t being worked on in Pakistan. Hardware / Software tradeoffs Buildings and units were restricted to a certain number to avoid any lags in the functionality of the game. The buildings for now have been kept to seven and units are five. These units function efficiently in the game and are extendable as new versions are introduced on later stages. Revenue model is simplistic for now, the game is free to download and play initially for a trial period of thirty days, once this trial period is over the game will be downloaded after paying nominal charges. Later on the game will work on Freemium model according to which it will be free to download but as the game proceeds there will be charges for proprietary features, functionality, or virtual goods. Another revenue earning feature would be banner advertisements which would be imported from Google library. FCS IBA Page 9 War Champions The game is easily extensible with graphic illustrations; it will be extended to Windows phones and various tablets. About ten to fifteen hours playtime campaign mode feature will also be introduced. Skills: Developers, Graphic Designers & Manager Resources: Game Engine: UNITY 3D-Unity allows users to create games once and then compile for desktop, web, mobile (iPhone and Android) and the big three consoles (Wii, PS3, XBox). 3D modeling tools: Used to create every object in a game .MAYA 3D /Blender will be used for this purpose. Texturing: .This is done to adjust normal maps, specularity, reflections, and light mapping etc. of the objects that are created. Adobe CS5 will be used for this purpose. Shaders: Shaders work on the surfaces of objects to give them different properties – they calculate the shininess, the softness of the lights and shadows, the transparency, reflection, refraction, and all the rest. Unity3D Built-in Shaders Unity3D Image Effects Development Frameworks: Mono – An open source implementation of the .NET framework, used by game engines like Unity3D to compile for multiple platform targets. Patents, copyright and trademarks Most of the models were purchased and downloaded from the unity 3D asset store. Among these were models of castles, soldiers, watch towers, bridges, vehicles, and different characters like soldiers, samurai, some sci-fi characters and many others. Various other links were used to download assets for War Champions. These are listed as follows: https://www.assetstore.unity3d.com/en/ archive3d.net/ tf3dm.com/ FCS IBA Page 10 War Champions https://kickass.so/unity-asset-fps-kit-version-2-0-1-6-0-1-jul-07-2014-requestedakd-t9880076.html Software / Hardware Design: Program Details Overview A. Possible Solutions and design alternatives: The Game will have client server architecture for Multiplayer Implementation. To start a game each player communicates to our master server that they are creating a game and define the parameters for that game and then they wait for the players to join. The Master server displays that game to all clients who connect to it looking for a game. The Player who created the game can start it once enough players have connected to FCS IBA Page 11 War Champions it. The player who created the game is the sever and all other players are clients. The server will be responsible for syncing of state and ensuring that no cheating occurs. Physics Libraries will be used to ensure that physic calculations on different devices for the same function always give the same output. Use of floats will also be avoided as they can cause syncing issues on devices with differing hardware. Syncing will be done by Transferring inputs across devices, and then attempting to get the same deterministic output from the other devices simulation, this is possible by eliminating any calculations in the shared engine code that calculates different values each time with the same input. (As can be seen from the diagrams below) The Campaign (offline) mode is less complicated and for each level the actions of the opposing AI will be scripted (“The enemies will do the same thing each time level is run”) The Unity 3D Game engine will handle all the rendering and environment creation and other aspects of the game. .Figure 5 – System Level Overview B FCS IBA Page 12 War Champions C. Module Level Descriptions a. Graphical User Interface Modules FCS IBA Page 13 War Champions The NGUI plugin for unity will be used for building GUI along with default unity GUI library. b. Control Modules The Unity Game Engine will handle most of the controlling of the app. But we will develop multiple modules for the controlling of Ads in the game and for players interaction with the environment. c. Miscellaneous Modules Photon Unity Networking (PUN) plus library will be used for networking. D. Assessment of Proposed Solution There are a large amount of ways to implement the networking logic in this game, The s simplest is to simplest is simply to send input. Another way would have been to send positional updates each frames, however this takes up too much bandwidth if there are a large amount of units on the screen, especially for mobile devices. User interface Output screens of prototype Figure 6- PLAYER 1’S TERRITORY FCS IBA Page 14 War Champions Figure 7- PLAYER 2’S TERRITORY Figure 8– UNITS COMING OUT OF BUILDINGS FCS IBA Page 15 War Champions : Figure 9-PLAYER 1 AND PLAYER 2 ATTACKING EACHOTHER Figure 10-PLAYER 1 CONQUERING PLAYER 2’S TERRITORY BY CAPURTING PLAYER 2’S HEADQUARTER AND DEFEATING PLAYER 2’S ARMY FCS IBA Page 16 War Champions Player 1 attacking player 2’s army Player 1 capturing player 2’s Headquarter FCS IBA Page 17 War Champions Errors There were a few lags experienced in certain situations. The units coming out of the attacking tower, hut and tower were rather too slow. Sometimes it would take a while and the player had to keep touching the button in order to get the units out. Another error that kept appearing was that the units kept walking while they fired towards their enemies. This could however not be controlled by the player as the player has no control over the movements of units, be it walking or attacking the opponent. This error could only be fixed by making changes in the source code of the game; was done on later on stage. When the option to place a building was clicked, a lot of time the buildings weren’t placed. Either no building appeared on the screen or the buildings which appeared could not be placed on the desired area. Along with this the clones weren’t coming out of the building a couple of times. These lags and errors were fixed on later on stage before deploying the game. Trails and tests In order to remove the lags that were experienced in the initial stage of development, improvement was done in the source code. After which validation was done by checking 4 buildings and 4 units for lag. Code was revised in order to fix another error which was related to locating the buildings on the field. Different onsite tests were conducted to check if buildings were being placed on the desired area or not. Clones were also coming out of the buildings after code was updated. These tests were performed on IOS and Android phones. We used IPhone 5 , IPhone 5s and IPhone 6 from Apple products and we used Samsung S3, S4 and Nexus 5 to check and run errors that were rectified. Unit testing and system testing was performed on the software before deployment. Firstly the fragments or units were tested to check if there was any lag or errors. Result of which showed that there were many lags and bugs which needed fixing. The number of buildings that could be placed was initially restricted to a couple and then eventually checks at exactly which number the lag started occurring. This test was carried out on Android Samsung S3 and on iPhone 5s. Both showed the same results. Then on later stages after rectifying these issues, a system test was carried out of the whole game to see if it persists, but it was covered and working without any lag after the rectification. FCS IBA Page 18 War Champions Hardware Details 1. IPhone 4 PLATFORM OS iOS 4, upgradable to iOS 7.1.1 Chipset Apple A4 CPU 1 GHz Cortex-A8 2. IPhone 5 PLATFORM OS iOS 6, upgradable to iOS 8.3 Chipset Apple A6 CPU Dual-core 1.3 GHz Swift (ARM v7-based) GPU PowerVR SGX 543MP3 (triple-core graphics) 3. IPhone 5s PLATFORM OS iOS 7, upgradable to iOS 8.3 Chipset Apple A7 CPU Dual-core 1.3 GHz Cyclone (ARM v8-based) GPU PowerVR G6430 (quad-core graphics) 4. IPhone 6 PLATFORM OS iOS 8, upgradable to iOS 8.3 Chipset Apple A8 CPU Dual-core 1.4 GHz Cyclone (ARM v8-based) GPU PowerVR GX6450 (quad-core graphics) 5. Samsung S3 PLATFORM OS Android OS, v4.0.4 (Ice Cream Sandwich), 4.3 (Jelly Bean) Chipset Exynos 4412 Quad CPU Quad-core 1.4 GHz Cortex-A9 GPU Mali-400MP4 6. Samsung S5 PLATFORM OS FCS IBA Android OS, v4.4.2 (KitKat), upgradable to v5.0 (Lollipop) Chipset Qualcomm MSM8974AC Snapdragon 801 CPU Quad-core 2.5 GHz Krait 400 GPU Adreno 330 Page 19 War Champions 7. Nexus 5 PLATFORM OS Android OS, v5.0 (Lolipop) Chipset Qualcomm MSM8974 Snapdragon 800 CPU Quad-core 2.3 GHz Krait 400 GPU Adreno 330 Results: We set out to create an online multiplayer cross platform mobile entertainment experience and we have achieved that. I believe that users of this genre will find out game attractive and entertaining for many hours. Due to limitations of time we had to cut back some of our features but we still managed to create a nice mobile multilayer experience. Conclusions: We conclude that we have achieved what we set out to create even though it doesn’t have all the features and as large content as we initially thought it would. We wanted a mobile multiplayer game that 2 people could play on different mobile devices together and we accomplished this. The feedback from the initial version is positive and game play is reported to be satisfying, however they would also like to see some more content within the game, like more buildings, different factions and units and even more maps. we have succeeded in providing our users with an entertaining experience. FCS IBA Page 20 War Champions Appendix: Appendix 1: Code using UnityEngine; using System.Collections; public class Arrow : MonoBehaviour { // The target will be set from whoever uses the arrow. // The arrow will fly towards the target and deal damage. public Transform target; // The fly speed public float speed = 5.0f; public bool damage; public GameObject hitAffect; FCS IBA Page 21 War Champions // Update is called once per frame void Update () { // target still alive? if (target != null) { // look at it transform.LookAt(target); // move towards it a bit more transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime); // reached it? if (transform.position == target.position) { // deal damage (this decrease the target's health by one) FCS IBA Page 22 War Champions if(damage) { --target.GetComponent<Health>().current; } // destroy arrow Instantiate(hitAffect, transform.position, transform.rotation); Destroy(gameObject); } } else { // if the target is dead, we are done Destroy(gameObject); } FCS IBA Page 23 War Champions } } ATTACK using UnityEngine; using System.Collections; using System.Collections.Generic; public class Attack : MonoBehaviour { // attack range public float range = 16.0f; // helper variables to attack every few seconds public float interval = 1.5f; float intervalElapsed = 0.0f; FCS IBA Page 24 War Champions private GameObject currentEnemy; // arrow prefab (to shoot at enemies) public GameObject arrow; private PhotonView photonView; NavMeshAgent navigator; private List<SpawnedUnit> enemyUnits; private List<PlaceableBuilding> enemyBuildings; void Start () { photonView = GetComponent<PhotonView> (); if (photonView.isMine) { if (GetComponent<SpawnedUnit> ().Team == 1) FCS IBA Page 25 War Champions { enemyUnits = SpawnedUnitHandler.Instance.team2; enemyBuildings = SpawnedUnitHandler.Instance.buildingsTeam2; } else { enemyUnits = SpawnedUnitHandler.Instance.team1; enemyBuildings = SpawnedUnitHandler.Instance.buildingsTeam1; } navigator = GetComponent<NavMeshAgent> (); } } // Update is called once per frame FCS IBA Page 26 War Champions void Update () { if (photonView.isMine) { intervalElapsed += Time.deltaTime; if (currentEnemy != null) { if (intervalElapsed >= interval) { photonView.RPC ("DoAttack", currentEnemy.GetPhotonView ().viewID); PhotonTargets.AllViaServer, intervalElapsed = 0; // navigator.Stop(true); } } else { FCS IBA Page 27 War Champions if (intervalElapsed >= interval) { // attack any enemy unit that is close enough foreach (SpawnedUnit g in enemyUnits) { // still alive? if (g != null) { if (Vector3.Distance (g.transform.position, transform.position) <= range) { // look at the target photonView.RPC ("DoAttack", g.GetComponent<PhotonView> ().viewID); PhotonTargets.AllViaServer, currentEnemy = g.gameObject; navigator.Stop (true); // done for now FCS IBA Page 28 War Champions intervalElapsed = 0.0f; return; } } } foreach (PlaceableBuilding b in enemyBuildings) { if (b != null) { if (Vector3.Distance (b.transform.position, transform.position) <= range) { // look at the target photonView.RPC ("DoAttack", b.GetComponent<PhotonView> ().viewID); PhotonTargets.AllViaServer, CurrentEnemy = b.gameObject; navigator.Stop (true); // done for now intervalElapsed = 0.0f; FCS IBA Page 29 War Champions return; } } // still alive? // reset interval intervalElapsed = 0.0f; } if (currentEnemy == null) { navigator.Resume (); } } // ready for the next attack? } } } [RPC] public void DoAttack (int photonID) { PhotonView tempPhoton = PhotonView.Find (photonID); FCS IBA Page 30 War Champions transform.LookAt (tempPhoton.gameObject.transform); // start new shoot animation GetComponent<AnimationSinus> ().toggle (); // create an arrow (just to have some visual feedback) GameObject a = (GameObject)Instantiate (arrow,transform.position, // default position Quaternion.identity); // default rotation // set its target a.GetComponent<Arrow> ().target = tempPhoton.gameObject.transform; this.currentEnemy = tempPhoton.gameObject; if (photonView.isMine) { a.GetComponent<Arrow> ().damage = true; } else FCS IBA Page 31 War Champions { a.GetComponent<Arrow> ().damage = false; } } } ATTACKABLE BUILDING: using UnityEngine; using System.Collections; using System.Collections.Generic; public class AttackAbleBuilding : MonoBehaviour { // attack range public float range = 16.0f; FCS IBA Page 32 War Champions // helper variables to attack every few seconds public float interval = 1.5f; float intervalElapsed = 0.0f; public GameObject AttackPoint; private GameObject currentEnemy; // arrow prefab (to shoot at enemies) public GameObject arrow; private PhotonView photonView; private List<SpawnedUnit> enemyUnits; void Start () { FCS IBA Page 33 War Champions photonView = GetComponent<PhotonView> (); if (photonView.isMine) { if (GetComponent<PlaceableBuilding> ().TeamNumber == 1) { enemyUnits = SpawnedUnitHandler.Instance.team2; } else { enemyUnits = SpawnedUnitHandler.Instance.team1; } } } // Update is called once per frame FCS IBA Page 34 War Champions void Update () { if (photonView.isMine) { intervalElapsed += Time.deltaTime; if (currentEnemy != null) { if (intervalElapsed >= interval) { photonView.RPC ("DoAttack", currentEnemy.GetPhotonView ().viewID); PhotonTargets.AllViaServer, intervalElapsed = 0.0f; // navigator.Stop(true); } FCS IBA Page 35 War Champions } else { if (intervalElapsed >= interval) { // attack any enemy unit that is close enough foreach (SpawnedUnit g in enemyUnits) { // still alive? if (g != null) { if (Vector3.Distance (g.transform.position, transform.position) <= range) { // look at the target FCS IBA Page 36 War Champions photonView.RPC ("DoAttack", g.GetComponent<PhotonView> ().viewID); PhotonTargets.AllViaServer, currentEnemy = g.gameObject; // done for now intervalElapsed = 0.0f; return; } } } // still alive? // reset interval intervalElapsed = 0.0f; } } FCS IBA Page 37 War Champions // ready for the next attack? } } [RPC] public void DoAttack (int photonID) { PhotonView tempPhoton = PhotonView.Find (photonID); // start new shoot animation // GetComponent<AnimationSinus> ().toggle (); // create an arrow (just to have some visual feedback) GameObject a = (GameObject)Instantiate (arrow, AttackPoint.transform.position, // default position Quaternion.identity); // default rotation FCS IBA Page 38 War Champions // set its target a.GetComponent<Arrow> ().target = tempPhoton.gameObject.transform; this.currentEnemy = tempPhoton.gameObject; if (photonView.isMine) { a.GetComponent<Arrow> ().damage = true; } else { a.GetComponent<Arrow> ().damage = false; } } } BUILDING MANAGER: FCS IBA Page 39 War Champions using UnityEngine; using System.Collections; using System.Collections.Generic; public class BuildingManager : Singleton<BuildingManager> { public List<BuildingsInfo> buildings; public BuildingPlacement buildingPlacement; private Camera mainCamera; public int Team; protected BuildingManager () {} // Use this for initialization void Start () { FCS IBA Page 40 War Champions //buildingPlacement = GetComponent<BuildingPlacement>(); mainCamera = GameObject.FindWithTag("MainCamera").GetComponent<Camera>(); } void Awake() { } // Update is called once per frame void Update () { } void OnGUI() { for(int i=0; i< buildings.Count; i++) FCS IBA Page 41 War Champions { if(GUI.Button(new Rect(Screen.width/20, Screen.height/15 + Screen.height/12 * i, 100,30), buildings[i].Building.name)) { buildingPlacement.SetItem(i); } } } } BUILDING PLACEMENT: using UnityEngine; u sing System.Collections; using UnityEngine.EventSystems; FCS IBA Page 42 War Champions using System.Collections.Generic; public class BuildingPlacement : Singleton<BuildingPlacement> { int layerMaskForPlacement = 1 << 9; public LayerMask layerMaskForSelection; private Transform CurrentBuilding; PlaceableBuilding placeableBuilding; public bool hasPlaced; private PlaceableBuilding oldPlaceAbleBuilding; private Camera mainCamera; private int currentBuildingID; protected BuildingPlacement() FCS IBA Page 43 War Champions { hasPlaced = true; } //private PhotonView photonView; // Use this for initialization void Start () { mainCamera = GameObject.FindWithTag ("MainCamera").GetComponent<Camera> (); layerMaskForPlacement = 1 << 9; //photonView = this.GetComponent<PhotonView>(); } // Update is called once per frame FCS IBA Page 44 War Champions void Update () { //Debug.Log(!EventSystem.current.IsPointerOverGameObject ()); if (CurrentBuilding != null && !hasPlaced) { Ray ray = mainCamera.ScreenPointToRay (Input.mousePosition); RaycastHit hit; if (Physics.Raycast (ray, out hit, 80.0F, layerMaskForPlacement)) { Vector3 newPosition = hit.point; Debug.DrawRay (ray.origin, ray.direction * 70, Color.yellow); CurrentBuilding.position = newPosition; if (isLegalPosition ()) { FCS IBA Page 45 War Champions placeableBuilding.SetTint (Color.white); } else { placeableBuilding.SetTint (Color.red); } } if (Input.GetMouseButtonDown (0)) { if (isLegalPosition ()) { GameObject TempBuiding = PhotonNetwork.Instantiate (BuildingManager.Instance.buildings [currentBuildingID].buildingName, CurrentBuilding.position, CurrentBuilding.rotation, 0); // PlaceableBuilding TempBuiding.GetComponent<PlaceableBuilding>(); FCS IBA TempPlaceAble = Page 46 War Champions hasPlaced = true; Destroy (CurrentBuilding.gameObject); } } // Vector3 m = Input.mousePosition; // m = new Vector3(m.x, m.y, transform.position.z); // Vector3 p = camera.ScreenToWorldPoint(m); } else { //EventSystem.current.UpdateModules (); if (!IsPointerOverUIObject()) { if (Input.GetMouseButtonDown (0)) { Ray ray = mainCamera.ScreenPointToRay (Input.mousePosition); FCS IBA Page 47 War Champions RaycastHit hit; if (Physics.Raycast (ray, out hit, 80.0F, layerMaskForSelection)) { Debug.Log (hit.collider.name); Debug.DrawRay (ray.origin, ray.direction * 70, Color.green); if (oldPlaceAbleBuilding != null) { oldPlaceAbleBuilding.SetSlected (false); } PlaceableBuilding tempBuilding hit.collider.gameObject.GetComponent<PlaceableBuilding> (); = if (tempBuilding.GetComponent<PhotonView> ().isMine) { tempBuilding.SetSlected (true); oldPlaceAbleBuilding = tempBuilding; FCS IBA Page 48 War Champions } } } } else { if (oldPlaceAbleBuilding != null) { oldPlaceAbleBuilding.SetSlected (false); } } } } FCS IBA Page 49 War Champions private bool IsPointerOverUIObject() { // Referencing this code https://gist.github.com/stramit/ead7ca1f432f3c0f181f for GraphicRaycaster // the ray cast appears to require only eventData.position. PointerEventData eventDataCurrentPosition PointerEventData(EventSystem.current); eventDataCurrentPosition.position Input.mousePosition.y); = new = new Vector2(Input.mousePosition.x, List<RaycastResult> results = new List<RaycastResult>(); EventSystem.current.RaycastAll(eventDataCurrentPosition, results); return results.Count > 0; } public bool isLegalPosition () { FCS IBA Page 50 War Champions if (placeableBuilding.colliders.Count > 0) { return false; } else { if (placeableBuilding.isInTeamBuildSpace) { return true; } } return false; } public void SetItem (int ID) { //Debug.Log (b.name); FCS IBA Page 51 War Champions if (hasPlaced) { hasPlaced = false; currentBuildingID = ID; CurrentBuilding = ((GameObject)Instantiate [ID].Building)).transform; (BuildingManager.Instance.buildings //CurrentBuilding ((GameObject)BuildingManager.buildings[ID]).transform; = placeableBuilding CurrentBuilding.gameObject.GetComponent<PlaceableBuilding> (); = placeableBuilding.TeamNumber BuildingManager.Instance.Team; = if (oldPlaceAbleBuilding != null) { oldPlaceAbleBuilding.SetSlected (false); } FCS IBA Page 52 War Champions } } } BUILDINGS INFO: using UnityEngine; using System.Collections; [System.Serializable] public class BuildingsInfo { public string buildingName; public GameObject Building; } FCS IBA Page 53 War Champions BUILD MENU: if (instance != null) { // Find out the 3D world coordinates under the cursor Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { if (hit.transform.name == "Ground") { // Refresh the instance position instance.transform.position = hit.point; // Note: if your castle appears to be 'in' the Ground // FCS IBA instead of 'on' the ground, you may have to adjust Page 54 War Champions // the y coordinate like so: //instance.transform.position += new Vector3(0, 1.23f, 0); } } // Player clicked? Then stop positioning the castle by simply // loosing track of our instance. Its still in the game world after- // wards, but we just can't position it anymore. if (Input.GetMouseButton(0)) { instance = null; } } FCS IBA Page 55 War Champions } void OnGUI() { GUILayout.BeginArea(new Rect(Screen.width/2 - width/2, Screen.height - height,width,height), "", "box"); // Disable the building button if we are currently building something. // Note: this enables GUIs if we have no instance at the moment, and // it disables GUIs if we currently have one. Its just written in // a fancy way. (it can also be done with a if-else construct) GUI.enabled = (instance == null); if (GUILayout.Button("BUILD CASTLE")) { // Instantiate the prefab and keep track of it by assigning it to // our instance variable. FCS IBA Page 56 War Champions instance = (GameObject)GameObject.Instantiate(prefab); } GUILayout.EndArea(); } } CAMERA MOVEMENT: using UnityEngine; using System.Collections; public class CameraMovement : MonoBehaviour { private Touch touch; public Camera cameraToMove; BuildingPlacement buildPlace; FCS IBA Page 57 War Champions // Use this for initialization void Start () { buildPlace = BuildingPlacement.Instance; } Vector3 cameraPos; // Update is called once per frame void Update () { cameraPos = cameraToMove.transform.position; if(Input.GetKey(KeyCode.A)) FCS IBA Page 58 War Champions { cameraPos.z += 1.5f; } if(Input.GetKey(KeyCode.D)) { cameraPos.z -= 1.5f; } if(Input.GetKey(KeyCode.W)) { cameraPos.x += 1.5f; } if(Input.GetKey(KeyCode.S)) FCS IBA Page 59 War Champions { cameraPos.x -= 1.5f; } //Movement From TouchInput. if(buildPlace.hasPlaced) { if (Input.touchCount == 1 && Input.GetTouch (0).phase == TouchPhase.Moved) { //One finger touch does orbit touch = Input.GetTouch (0); FCS IBA Page 60 War Champions cameraPos.x -= touch.deltaPosition.y *0.4f ; cameraPos.z += touch.deltaPosition.x * 0.4f ; //usingMouse = false; } } cameraToMove.transform.position = cameraPos; } // // // void Update () FCS IBA Page 61 War Champions // { // // // if (target && camera) { // // // #if UNITY_EDITOR // // //Detect mouse drag; // // FCS IBA Page 62 War Champions if (Input.GetMouseButton (0)) { // // //gotFirstTouchInput = true; // // // x += Input.GetAxis ("Mouse X") * xSpeed;// * 0.4f; // * 0.02f; // // // lastMovedAng.x = Input.GetAxis ("Mouse X"); // lastMovedAng.y = Input.GetAxis ("Mouse Y"); // FCS IBA Page 63 War Champions // // // } else { // x += lastMovedAng.x * xSpeed * 0.01f; // y -= lastMovedAng.y * ySpeed * 0.01f; // } // // #else // // // if (Input.touchCount == 1 && Input.GetTouch (0).phase == TouchPhase.Moved) { FCS IBA Page 64 War Champions // // //One finger touch does orbit // // touch = Input.GetTouch (0); // // x += touch.deltaPosition.x * xSpeed * 0.02f; // // y -= touch.deltaPosition.y * ySpeed * 0.02f; // //usingMouse = false; // // lastMovedAng.x = touch.deltaPosition.x; // lastMovedAng.y = touch.deltaPosition.y; FCS IBA Page 65 War Champions // } else { // // x += lastMovedAng.x * xSpeed * 0.0006f; // y -= lastMovedAng.y * ySpeed * 0.0006f; // } // // // // // FCS IBA Page 66 War Champions // // if (Input.touchCount > 1 && (Input.GetTouch (0).phase == TouchPhase.Moved || Input.GetTouch (1).phase == TouchPhase.Moved)) { // // // // // Two finger touch does pinch to zoom // // // // var touch1 = Input.GetTouch (0); // FCS IBA Page 67 War Champions // // // var touch2 = Input.GetTouch (1); // // // curDist = Vector2.Distance (touch1.position, touch2.position); // // // // if (curDist > lastDist) { // // FCS IBA Page 68 War Champions // // distance += Vector2.Distance (touch1.deltaPosition, touch2.deltaPosition) * pinchSpeed / 10; // // // // } else { // // // // distance -= Vector2.Distance (touch1.deltaPosition, touch2.deltaPosition) * pinchSpeed / 10; // // // // FCS IBA Page 69 War Champions } // // // // // // // // lastDist = curDist; // // // // } // FCS IBA Page 70 War Champions // // #endif // // // y = ClampAngle (y, yMinLimit, yMaxLimit); // // transform.position = Vector3.Lerp (transform.position, position, cameraSpeed * Time.deltaTime); // // } // // FCS IBA Page 71 War Champions } } CASTLE NPC: using UnityEngine; using System.Collections; public class CastleNpc : MonoBehaviour { // Parameters public float spawnInterval = 3.0f; float spawnIntervalElapsed = 0.0f; void Update() { // Build it every few seconds spawnIntervalElapsed += Time.deltaTime; FCS IBA Page 72 War Champions if (spawnIntervalElapsed >= spawnInterval) { // Use UnitSpawner GetComponent<UnitSpawner>().spawn(); // Reset interval spawnIntervalElapsed = 0.0f; } } } CASTLE PLAYER: using UnityEngine; using System.Collections; public class CastlePlayer : MonoBehaviour { FCS IBA Page 73 War Champions // Note: OnMouseDown only works if object has a collider void OnMouseDown() { // Only if animation finished if (!GetComponent<AnimationSinus>().inProgress()) { Debug.Log("Castle Clicked"); // use UnitSpawner // GetComponent<UnitSpawner>().spawn(); } } } HEALTH: using UnityEngine; FCS IBA Page 74 War Champions using System.Collections; public class Health : MonoBehaviour { public int current = 4; public Color color = Color.red; PhotonView photonView; void Start () { photonView = GetComponent<PhotonView>(); } // Update is called once per frame void Update () { FCS IBA Page 75 War Champions // set 3d text to '----', '---', '--', '-' or '' TextMesh tm = GetComponentInChildren<TextMesh>(); if(current >0) { tm.text = new string('-', current); } // set 3d text color tm.renderer.material.color = color; // optional: make it look horizontally by facing the camera // (uncomment it to see how it looks otherwise) tm.transform.forward = Camera.main.transform.forward; } FCS IBA Page 76 War Champions // LateUpdate is called after all Update functions have been called void LateUpdate() { // dead? if(photonView.isMine) { if (current <= 0) { PhotonNetwork.Destroy(gameObject); } } } } FCS IBA Page 77 War Champions LASER ATTACK TOWER: using UnityEngine; using System.Collections; using System.Collections.Generic; public class LaserAttackTower : MonoBehaviour { public float range = 16.0f; // helper variables to attack every few seconds public float interval = 1.5f; float intervalElapsed = 0.0f; public GameObject AttackPoint; public GameObject TurretHead; FCS IBA Page 78 War Champions private GameObject currentEnemy; bool ShouldFireLaser; private PhotonView photonView; private List<SpawnedUnit> enemyUnits; private LineRenderer line; void Start () { photonView = GetComponent<PhotonView> (); line = this.GetComponentInChildren<LineRenderer>(); if (photonView.isMine) { if (GetComponent<PlaceableBuilding> ().TeamNumber == 1) { FCS IBA Page 79 War Champions enemyUnits = SpawnedUnitHandler.Instance.team2; } else { enemyUnits = SpawnedUnitHandler.Instance.team1; } } } // Update is called once per frame void Update () { if (photonView.isMine) { intervalElapsed += Time.deltaTime; FCS IBA Page 80 War Champions if (currentEnemy != null) { if (intervalElapsed >= interval) { photonView.RPC ("DoAttack", PhotonTargets.AllViaServer, currentEnemy.GetPhotonView ().viewID); intervalElapsed = 0.0f; // navigator.Stop(true); } } else { if (intervalElapsed >= interval) { // attack any enemy unit that is close enough FCS IBA Page 81 War Champions foreach (SpawnedUnit g in enemyUnits) { // still alive? if (g != null) { if (Vector3.Distance (g.transform.position, transform.position) <= range) { // look at the target photonView.RPC ("DoAttack", PhotonTargets.AllViaServer, g.GetComponent<PhotonView> ().viewID); currentEnemy = g.gameObject; // done for now intervalElapsed = 0.0f; return; } FCS IBA Page 82 War Champions } } // still alive? // reset interval intervalElapsed = 0.0f; } } // ready for the next attack? } } [RPC] public void StartLaser (int photonID) FCS IBA Page 83 War Champions { PhotonView tempPhoton = PhotonView.Find (photonID); // // start new shoot animation // GameObject a = (GameObject)Instantiate (arrow, //AttackPoint.transform.position, // default position //Quaternion.identity); // default rotation // // // set its target // a.GetComponent<Arrow> ().target = tempPhoton.gameObject.transform; // this.currentEnemy = tempPhoton.gameObject; // if (photonView.isMine) { // a.GetComponent<Arrow> ().damage = true; // } else { FCS IBA Page 84 War Champions // a.GetComponent<Arrow> ().damage = false; // } } IEnumerator LaserBeam() { line.enabled = true; while(ShouldFireLaser) { if(currentEnemy != null) { TurretHead.transform.LookAt(currentEnemy.transform.position); FCS IBA Page 85 War Champions line.SetPosition(0, AttackPoint.transform.position); line.SetPosition(1, currentEnemy.transform.position); } yield return null; } line.enabled = false; } } MOVE BY NPC: //using UnityEngine; FCS IBA Page 86 War Champions //using System.Collections; // // public class MoveByNpc : MonoBehaviour { // // // Update is called once per frame // void Update () { // // find the attack range // float range = GetComponent<Attack>().range; // // // find all enemy units // FCS IBA Page 87 War Champions string enemyTag;// = GetComponent<Attack>().enemyTag; // GameObject[] units = GameObject.FindGameObjectsWithTag(enemyTag); // // // is there any unit that is in attack range already? if so, then there // // is nothing to do right now // foreach (GameObject g in units) { // // still alive? // if (g != null) { // if (Vector3.Distance(transform.position, g.transform.position) <= range) { // return; FCS IBA Page 88 War Champions // } // } // } // // // already moving somewhere? then do nothing for now // if (GetComponent<NavMeshAgent>().hasPath) { // return; // } // // // // pick a random target (if there are any) FCS IBA Page 89 War Champions // if (units.Length > 0) { // int index = Random.Range(0, units.Length); // GameObject u = units[index]; // // // still alive? // if (u != null) { // // move close enough so we are in attack range // Vector3 pos = transform.position; // Vector3 target = u.transform.position; // FCS IBA Page 90 War Champions // Vector3 dir = target - pos; // dir = dir.normalized; // Vector3 dest = pos + dir * (Vector3.Distance(target, pos) - range); // // // tell the navmesh agent to go there // GetComponent<NavMeshAgent>().destination = dest; // } // } // } // } MOVE BY PLAYER: FCS IBA Page 91 War Champions using UnityEngine; using System.Collections; public class MoveByPlayer : MonoBehaviour { // Update is called once per frame void Update () { // Rightclicked while selected? if (Input.GetMouseButtonDown(1) && isSelected()) { // Find out where the user clicked in the 3D world Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) FCS IBA Page 92 War Champions { GetComponent<NavMeshAgent>().destination = hit.point; } } } // Find out if its selected (if the selection circle is visible) bool isSelected() { MeshRenderer[] children = GetComponentsInChildren<MeshRenderer>(); foreach (MeshRenderer r in children) { if (r.gameObject.name == "SelectionCircle" && r.enabled) { return true; FCS IBA Page 93 War Champions } } return false; } } PLACEABLE BUILDING: using UnityEngine; using System.Collections; using System.Collections.Generic; public class PlaceableBuilding : MonoBehaviour { public int TeamNumber; FCS IBA Page 94 War Champions public GameObject ConstructableUnits; public GameObject UnitConstructionPos; bool isSelected = false; public bool isInTeamBuildSpace = false; [HideInInspector] public List<Collider> colliders = new List<Collider> (); // Use this for initialization PhotonView photonView; void Start () { //this.TeamNumber = BuildingManager.Instance.Team; FCS IBA Page 95 War Champions if(photonView == null) { this.photonView = this.GetComponent<PhotonView>(); } //UpdateTeam (); } public void SetTint (Color c) { gameObject.GetComponentInChildren<Renderer> ().material.color = c; } public void SetSlected (bool s) FCS IBA Page 96 War Champions { isSelected = s; if (isSelected) { SetTint (Color.green); } else { SetTint (Color.white); } Debug.Log ("Team Number:" + TeamNumber); } public void UpdateTeam () FCS IBA Page 97 War Champions { if(photonView.isMine) { TeamNumber = BuildingManager.Instance.Team; } else { if (BuildingManager.Instance.Team == 1) { TeamNumber = 2; } else { FCS IBA Page 98 War Champions TeamNumber = 1; } } } void OnGUI () { if (isSelected) { if (ConstructableUnits != null) { if (GUI.Button (new Rect (100, 200, 100, 30), name)) { Debug.Log ("Button Child Clicked"); FCS IBA Page 99 War Champions //Instantiate(ConstructableUnits, UnitConstructionPos.transform.position, UnitConstructionPos.transform.rotation); this.GetComponent<PhotonView> ().RPC ("InstantiateUnitOverNetwork", PhotonTargets.All, TeamNumber); } } } } [RPC] public void InstantiateUnitOverNetwork (int TeamNumber) { Debug.Log ("Rpc Called"); if (PhotonNetwork.isMasterClient) { Debug.Log (ConstructableUnits.name); FCS IBA Page 100 War Champions GameObject temp = PhotonNetwork.InstantiateSceneObject (ConstructableUnits.name, UnitConstructionPos.transform.position, UnitConstructionPos.transform.rotation, 0, null); //temp.GetComponent<PhotonView>().; // SpawnedUnitHandler.Instance.AddToTeam (temp.GetComponent<SpawnedUnit> (), TeamNumber); this.GetComponent<PhotonView> ().RPC ("AssingUnitTeams", PhotonTargets.All, temp.GetComponent<PhotonView>().viewID, TeamNumber); Debug.Log (temp.name); Debug.Log ("is master client"); } } [RPC] public void AssingUnitTeams(int ViewID, int Team) { PhotonView tempPhoton = PhotonView.Find (ViewID); FCS IBA Page 101 War Champions tempPhoton.GetComponent<SpawnedUnit>().Team = Team; SpawnedUnitHandler.Instance.AddToTeam(tempPhoton.GetComponent<SpawnedUnit>(), TeamNumber); } void OnTriggerEnter (Collider c) { if (c.tag == "Building") { Debug.Log ("collided with building"); colliders.Add (c); } Debug.Log ("Team" + TeamNumber + "Terrain"); if (c.tag == ("Team" + TeamNumber + "Terrain")) FCS IBA Page 102 War Champions { Debug.Log ("in Team Space"); isInTeamBuildSpace = true; } } void OnTriggerExit (Collider c) { if (c.tag == "Building") { colliders.Remove (c); } else if (c.tag == ("Team" + TeamNumber + "Terrain")) { Debug.Log ("not in team Space"); isInTeamBuildSpace = false; FCS IBA Page 103 War Champions } } void OnPhotonInstantiate(PhotonMessageInfo info) { if(photonView == null) { this.photonView = this.GetComponent<PhotonView>(); } this.UpdateTeam(); SpawnedUnitHandler.Instance.AddToListBuilding(this); Debug.Log("instantiate called"); } FCS IBA Page 104 War Champions void OnMouseDown () { // Only if animation finished //if (!GetComponent<AnimationSinus>().inProgress()) { Debug.Log ("Castle Clicked"); // use UnitSpawner // GetComponent<UnitSpawner>().spawn(); } } RANDOM MATCH MAKER: using UnityEngine; public class RandomMatchMaker : MonoBehaviour FCS IBA Page 105 War Champions { public ShowStatusWhenConnecting statusUI; public GameObject[] ObjectsToActivateInRoom; // Use this for initialization void Start () { //PhotonNetwork.ConnectUsingSettings ("0.1"); } void OnGUI () { GUILayout.Label (PhotonNetwork.connectionStateDetailed.ToString ()); FCS IBA Page 106 War Champions } void Update() { if(PhotonNetwork.connectionStateDetailed == PeerState.PeerCreated) { statusUI.enabled = true; } } void OnJoinedLobby () { FCS IBA Page 107 War Champions //PhotonNetwork.JoinRandomRoom (); } void OnPhotonRandomJoinFailed () { Debug.Log ("Can't join random room!"); PhotonNetwork.CreateRoom (null); } void OnPhotonPlayerConnected (PhotonPlayer newPlayer) { } FCS IBA Page 108 War Champions void OnJoinedRoom () { foreach (GameObject obj in ObjectsToActivateInRoom) { obj.SetActive (true); } if (PhotonNetwork.playerList.Length == 1) { BuildingManager.Instance.Team = 1; } else { FCS IBA Page 109 War Champions BuildingManager.Instance.Team = 2; } Debug.Log("Team# " + BuildingManager.Instance.Team); } } SELECTION: //using UnityEngine; //using System.Collections; // // public class Selection : MonoBehaviour { // // Selection rectangle // FCS IBA Page 110 War Champions Vector2 start = new Vector2(0, 0); // Vector2 cur = new Vector2(0, 0); // bool visible = false; // // Rect currentRect() { // // Create a rect from the current start & cur points // Vector2 min = new Vector2(Mathf.Min(start.x, cur.x), // Mathf.Min(start.y, cur.y)); // Vector2 max = new Vector2(Mathf.Max(start.x, cur.x), FCS IBA Page 111 War Champions // Mathf.Max(start.y, cur.y)); // return new Rect(min.x, min.y, max.x-min.x, max.y-min.y); // } // // // Update is called once per frame // void Update () { // // Multi Selection started // if (Input.GetMouseButtonDown(0)) { // // Set rect position to current mouse position // FCS IBA Page 112 War Champions start.x = Input.mousePosition.x; // start.y = Screen.height - Input.mousePosition.y; // visible = true; // } // // // Multi Selection in progress? // if (Input.GetMouseButton(0)) { // // Update rect // cur.x = Input.mousePosition.x; // cur.y = Screen.height - Input.mousePosition.y; // } // FCS IBA Page 113 War Champions // // Multi Selection finished? // if (Input.GetMouseButtonUp(0)) { // // Set select status for each of the player's units: // GameObject[] units = GameObject.FindGameObjectsWithTag("Player"); // foreach (GameObject g in units) { // // Still alive? // if (g != null) { // // World to screen position // Vector3 p = camera.WorldToScreenPoint(g.transform.position); // FCS IBA Page 114 War Champions Vector2 screenPos = new Vector2(p.x, Screen.height - p.y); // // Debug.Log("single selection break2" + g.name); // // // Is the position in the rectangle? // if (currentRect().Contains(screenPos)) { // setSelectionCircleVisiblity(g, true); // } else { // setSelectionCircleVisiblity(g, false); // } // } // } // FCS IBA Page 115 War Champions // // Don't draw the rectangle anymore // visible = false; // } // } // // void setSelectionCircleVisiblity(GameObject g, bool visible) { // MeshRenderer[] children = g.GetComponentsInChildren<MeshRenderer>(); // foreach (MeshRenderer r in children) { // if (r.gameObject.name == "SelectionCircle") { // // Make the selection circle visible or invisible by enabling or // // disabling its renderer // FCS IBA Page 116 War Champions r.enabled = visible; // } // } // } // // void OnGUI() { // // Selection Visible and mouse moved a bit? Then draw the rectangle // if (visible && !cur.Equals(start)) { // GUI.Box(currentRect(), ""); // } // } //} SINGLETON: FCS IBA Page 117 War Champions using UnityEngine; /// <summary> /// Be aware this will not prevent a non singleton constructor /// such as `T myT = new T();` /// To prevent that, add `protected T () {}` to your singleton class. /// /// As a note, this is made as MonoBehaviour because we need Coroutines. /// </summary> public class Singleton<T> : MonoBehaviour where T : MonoBehaviour { private static T _instance; private static object _lock = new object(); FCS IBA Page 118 War Champions public static T Instance { get { if (applicationIsQuitting) { Debug.LogWarning("[Singleton] Instance '"+ typeof(T) + "' already destroyed on application quit." + " Won't create again - returning null."); return null; } lock(_lock) { if (_instance == null) { _instance = (T) FindObjectOfType(typeof(T)); if ( FindObjectsOfType(typeof(T)).Length > 1 ) FCS IBA Page 119 War Champions { Debug.LogError("[Singleton] Something went really wrong " + " - there should never be more than 1 singleton!" + " Reopening the scene might fix it."); return _instance; } if (_instance == null) { GameObject singleton = new GameObject(); _instance = singleton.AddComponent<T>(); singleton.name = "(singleton) "+ typeof(T).ToString(); DontDestroyOnLoad(singleton); Debug.Log("[Singleton] An instance of " + typeof(T) + " is needed in the scene, so '" + singleton + "' was created with DontDestroyOnLoad."); } else { Debug.Log("[Singleton] Using instance already created: "+ FCS IBA Page 120 War Champions _instance.gameObject.name); SPAWNED UNIT: using UnityEngine; using System.Collections; public class SpawnedUnit : MonoBehaviour { public Transform EnemyCastleLocation; public int Team; PhotonView photonView; NavMeshAgent navigator; Health healthScript; // Use this for initialization FCS IBA Page 121 War Champions void Start () { if(photonView == null) { photonView = GetComponent<PhotonView>(); } navigator = GetComponent<NavMeshAgent>(); healthScript = GetComponent<Health>(); if(!photonView.isMine) { //rigidbody.isKinematic = false; navigator.enabled = false; healthScript = GetComponent<Health>(); FCS IBA Page 122 War Champions Team = 2; } else { if(EnemyCastleLocation != null) { GetComponent<NavMeshAgent>().destination = EnemyCastleLocation.position; } healthScript = GetComponent<Health>(); } } void Awake() FCS IBA Page 123 War Champions { if(photonView == null) { photonView = GetComponent<PhotonView>(); } if(!photonView.isMine) { Team = 2; } healthScript = GetComponent<Health>(); } FCS IBA Page 124 War Champions public void SetEnemyCastleLocation(Transform t) { EnemyCastleLocation = t; if(EnemyCastleLocation != null) { GetComponent<NavMeshAgent>().destination = EnemyCastleLocation.position; } } // Update is called once per frame void Update () { if(photonView.isMine) FCS IBA Page 125 War Champions { if(Input.GetKeyDown(KeyCode.Space)) { navigator.Stop(true); } //code to actually simulate movement etc //if we are the main player then the navmesh agent is taking care of it. } else { //code to sync movement recieved from update. make predictions etc. // transform.position = Vector3.Lerp(transform.position, correctPlayerPos, Time.deltaTime * this.SmoothingDelay); FCS IBA Page 126 War Champions syncTime += Time.deltaTime; if(syncTime <= syncDelay) { transform.position = Vector3.Lerp(syncStartPosition,syncEndPosition, syncTime/syncDelay); Debug.Log("synctime: " + syncTime + " , sync Delay: " + syncDelay + " .. " + syncTime/syncDelay); } else { if(syncTime > extraDelay) { extraDelay += syncDelay; FCS IBA Page 127 War Champions syncExtraPos = SyncPosition + (syncVelocity * extraDelay); } transform.position = Vector3.Lerp(syncEndPosition, syncExtraPos, syncTime/extraDelay); Debug.Log("EXTRAsynctime: " + syncTime + " , EXTRAA Delay: " + extraDelay + " .. " + syncTime/extraDelay); } } } private float lastSynchronizationTime = 0f; private float syncDelay = 0f; private float syncTime = 0f; private Vector3 syncStartPosition = Vector3.zero; private Vector3 syncEndPosition = Vector3.zero; FCS IBA Page 128 War Champions private Vector3 syncExtraPos = Vector3.zero; Vector3 SyncPosition; private float extraDelay; Vector3 syncVelocity; void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { if(stream.isWriting) { stream.SendNext(transform.position); if(navigator != null) { stream.SendNext(navigator.velocity); FCS IBA Page 129 War Champions } else { stream.SendNext(0.0f); } stream.SendNext(transform.rotation); stream.SendNext(healthScript.current); //stream.SendNext(rigidbody.rotation); } else { SyncPosition = (Vector3)stream.ReceiveNext(); FCS IBA Page 130 War Champions syncVelocity = (Vector3)stream.ReceiveNext(); Quaternion SyncRotation = (Quaternion)stream.ReceiveNext(); healthScript.current = (int)stream.ReceiveNext(); syncTime = 0f; syncDelay = Time.time - lastSynchronizationTime; lastSynchronizationTime = Time.time; extraDelay = syncDelay *2; transform.rotation = SyncRotation; syncEndPosition = SyncPosition + (syncVelocity * syncDelay); syncExtraPos = SyncPosition + (syncVelocity * extraDelay); syncStartPosition = transform.position; FCS IBA Page 131 War Champions } } void OnPhotonInstantiate(PhotonMessageInfo info) { if(photonView == null) { this.photonView = this.GetComponent<PhotonView>(); } if(photonView.isMine) { Team = BuildingManager.Instance.Team; } FCS IBA Page 132 War Champions else { if (BuildingManager.Instance.Team == 1) { Team = 2; } else { Team = 1; } } } FCS IBA Page 133 War Champions } SPAWNED UNIT HANDLER: using UnityEngine; using System.Collections; using System.Collections.Generic; public class SpawnedUnitHandler : Singleton<SpawnedUnitHandler> { public GameObject CastleTeam1; public GameObject CastleTeam2; public List<SpawnedUnit> team1; FCS IBA Page 134 War Champions public List<SpawnedUnit> team2; public List<PlaceableBuilding> buildingsTeam1; public List<PlaceableBuilding> buildingsTeam2; protected SpawnedUnitHandler() { team1 = new List<SpawnedUnit>(); team2 = new List<SpawnedUnit>(); // CastleTeam2.SetActive(true); // PlaceableBuilding place = CastleTeam2.GetComponent<PlaceableBuilding>(); // place.TeamNumber =2; } FCS IBA Page 135 War Champions public void AddToTeam(SpawnedUnit unit, int team) { unit.Team = team; if(team == 1) { unit.SetEnemyCastleLocation(CastleTeam2.transform); team1.Add(unit); } else { unit.SetEnemyCastleLocation(CastleTeam1.transform); team2.Add(unit); FCS IBA Page 136 War Champions } } public void AddToListBuilding(PlaceableBuilding building) { Debug.Log ("in SpawnedUnitHandler"); if (building.TeamNumber == 1) { buildingsTeam1.Add(building); Debug.Log("building added to list of team 1"); } else { FCS IBA Page 137 War Champions buildingsTeam2.Add(building); Debug.Log("building added to list of team 2"); } } // Use this for initialization void Start () { } // Update is called once per frame void Update () { FCS IBA Page 138 War Champions } void LateUpdate() { //code to remove spawned objects from list and destroy them here. } } UNIT SPAWNER: using UnityEngine; using System.Collections; public class UnitSpawner : MonoBehaviour { // unit prefab FCS IBA Page 139 War Champions public GameObject unit; public float spawnRange = 1.5f; public void spawn() { // start new animation GetComponent<AnimationSinus>().toggle(); // create a new unit at some random position around this place Vector3 pos = transform.position; float x = pos.x + Random.Range(-1.0f, 1.0f) * spawnRange; float y = pos.y; float z = pos.z + Random.Range(-1.0f, 1.0f) * spawnRange; float angle = Random.Range(0.0f, 360.0f); FCS IBA Page 140 War Champions Instantiate(unit, new Vector3(x, y, z), Quaternion.Euler(0.0f, angle, 0.0f)); } } FCS IBA Page 141 War Champions Appendix 4: Software/parts list a) b) c) d) e) f) g) h) Unity 3D Adobe Photoshop Blender 3dsmax MS word MS PowerPoint Windows Movie Maker Coral Draw FCS IBA Page 142 War Champions Appendix 5: Work distribution FOR FYP-1 A: Research Game Study Research Papers and Thesis Analysis of Different Modules Market Survey and Research B: Interviews Scheduling and Appointments Surveys and Questionnaire C Documentation Report PowerPoint Video Poster D: Logo Design Logo Name Logo Design FOR FYP-2 Task Coding Environments Units and Models Report Video Poster FCS IBA Syed Faraz Ahmed, Sarah Fatima and Varda Sarfraz Sarah Fatima and Varda Sarfraz Syed Faraz Ahmed Sarah Fatima and Varda Sarfraz Varda Sarfraz Sarah Fatima and Syed Faraz Ahmed Syed Faraz Ahmed, Sarah Fatima and Varda Sarfraz Faraz Ahmed Varda Sarfraz Sarah Fatima Faraz Ahmed and Varda Sarfraz Sarah Fatima Members Faraz Ahmed Varda Sarfraz Sarah Fatima Sarah Fatima , Varda Sarfraz, Faraz Ahmed Varda Sarfraz Sarah Fatima Page 143 War Champions Appendix 6: Project timeline For FYP-1 Date Progress Update on agenda 12 September Discussion on the type of project that would be undertaken and choosing the supervisor for the project Making a game decided as final year project. Different genres and types of games discussed to choose from Meeting with Dr. Sajjad Haider and discussion of FYP idea with him Research on different final years projects done in previous years at IBA and other universities 19 September 26 September 03 October Contacting software houses for collaboration 10 October Meeting with Mr. Alamgir and discussion on the details of the game (concept, genre, other features) Meeting and negotiations with 10 pearls for collaboration 17 October 24 October FOR FYP-II 1 Initial Development 2 Models and Units 3 Environments 4 Ready Prototype 5 Further Development 6 Deployment 7 Marketing FCS IBA Game concept finalized A list of games produced from which the concept of game and other ideas deduced Suggestion on the course of proceedings by him. Software and tools for game development also discussed Meeting with Mr. Syed Ahmed from 10 pearls and Mr. Alamgir from Alamgir and Co. Two concepts of game discussed and abstracts designed based on it Ground rules decided for collaboration and an agreement made Abstract under preparation and research on game development going on 23 Feb’15- 14 March’15 1 Feb’15 – 1 March’15 3 March’15- 8 March’15 7 April’15 7 April’15- 20 May’15 Till 20 May’15 20 May’15- 25 May’15 Page 144 War Champions References: Inspirations for code and designs: http://docs.unity3d.com/ScriptReference/index.html Papers: http://www.infosolutionsgroup.com/popcapmobile2013.pdf http://www.applift.com/The-Global-Mobile-Games-Market.pdf Background sites: http://www.businessofgames.com/mobile-games-market-double-size-2016-reach-239bn/#miBwS5cZCQpWXXmI.99 http://www.newzoo.com/insights/global-games-market-will-reach-102-9-billion-2017-2/ http://www.theguardian.com/technology/2014/oct/23/mobile-games-revenue-overtake-consoles2015 http://www.superdataresearch.com/market-data/mobile-games-market/ http://www.slideshare.net/mochimedia/2012-flash-games-market-survey-results https://www.idc.com/getdoc.jsp?containerId=IDC_P1332 http://www.applift.com/blog/mobile-games-market.html Acknowledgements: We would like to thank Mr. Syed Ahmed for guiding us and giving us an exclusive interview for our project. The interview is a part of the video of the game. FCS IBA Page 145 War Champions FCS IBA Page 146