moonsye
Development Blog
23 posts
A blog all about my work
Don't wanna be here? Send us removal request.
moonsye · 8 years ago
Text
Presenting Novicius
The place was HUGE!
We got to preset our game Novicius for the final time which is amazing but also very sad at the same time. My group and I have been working together for the past 9 month to create something we’re all proud of in the form of Novicius. Working with these guys has been an amazing experience that I don’t think I’d change any of it. I’m so proud to call these guys my friends, and I’m proud of what we all have created!
Tumblr media Tumblr media Tumblr media
1 note · View note
moonsye · 8 years ago
Text
Dissertation Overload
This week saw me focus more on my Dissertation more so then Novicius, I did this because I felt like I needed to step away from Novicius in order me to to be able to tackle it at 100% which I feel like I’ve slowly declined over the weeks from continuous work on the game.
0 notes
moonsye · 8 years ago
Text
The Case of the Missing Trees
So while playing randomly I came across invisible objects in odd places, not knowing what they were I opened the objects up in unity to find out what they could be. Turns out that they are trees that have their meshs missing, here are some of the pictures showing the locations.
Tumblr media Tumblr media Tumblr media Tumblr media
1 note · View note
moonsye · 8 years ago
Text
QA The Village
Looking around the village I only came across some clipping and collision issues, the funniest problem I found was randomly popping into a wooden pillar next to one of the huts, this was because of the collisions that were placed onto the hut but still made me chuckle. Some miner frame rate dips from the particle effects of the fire pit but that problem was easy to fix within the inspector.
Tumblr media Tumblr media Tumblr media Tumblr media
0 notes
moonsye · 8 years ago
Text
Looking Around Outside
Moving the testing from the inside of the ship to the outside opened a lot of different problems, ranging from clipping, missing objects and being able to walk on water (which I thought was pretty funny). Another problem that I found was some frame rate drops from non optimised objects within the world, I was unable to get a good image of this but this was from how high poly the maze was.
Tumblr media Tumblr media Tumblr media
The frame rate issue has since been fixed with the optimisation of the maze walls.
0 notes
moonsye · 8 years ago
Text
QA UI
I took some time to test out the UI for any bugs we might have missed so far, I did come across one that was more of a graphical glitch then anything. Within the inventory the player can see what items they have picked up and can select them which is shown by a green outline, the problem is when you first open the inventory and look at the items it looks like the player is selecting all the items within the inventory, and will vanish when you cycle through the items as shown in the pictures below.
Tumblr media Tumblr media
This problem has since been fixed but was an issue for a while.
0 notes
moonsye · 8 years ago
Text
QA Tester
With most of the AI coding done, I found myself switching over disciplines and becoming the QA (Quality Assurance) Tester, playing through the game that we have created to find anything that was broken or things that needed tweaking. The first area I played through was the beginning ship level where Eve wakes up before setting out onto the planet Novicius. I found a few different clipping issues which you can see in the images below, but overall I didn’t find any game breaking bug which is always good. 
Tumblr media Tumblr media Tumblr media
That last one with the character clipping into the ship camera is one of the funnier ones I came across.
0 notes
moonsye · 8 years ago
Text
Novicius Poster
So @essmcleandevgames one of our amazing artists has made a poster for our game. here it is!!
Tumblr media
Super proud of my whole team and how much we’re working to make this game.
0 notes
moonsye · 8 years ago
Text
Working On Animations
Sorting out animations is frustration! So to explain, I’m working on the Animations for the Enemy AI so it looks alive and isn’t doing the T pose everywhere. So the frustration part isn’t making animations its putting them together so they all fluidly switch to another once there done. Here’s what I’ve got.
Tumblr media
So far it’s only this but THIS took a while for me to work out. I can definetly say that I’ve learned something new.
0 notes
moonsye · 8 years ago
Text
It Speaks!
Since I’ve been working on the Companion AI, I took the chance to create the dialogue for him during the tutorial and design the tutorial itself. Here’s the script.
Fade In:
Intro Tutorial
Screen fades in seeing the player wake up in her chair as the companion flies in front of her.
Companion
Hey.
Companion
You’re finally awake!
Companion
That was some crash!
Companion
It looks like the ships still in lock down, you’ll need to restart the ship if you want to get out.
Companion
But first we have to go through safety protocol just in case anything’s happened to you.
(companion scans player)
Companion
Your vitals seem normal, try standing up.
(Companion shows interact button)
Companion
Great, try looking around.
(Companion shows camera controls)
Companion
Nice! The crash didn’t do that much damage to you… the ship however is worse off.
Companion
Go ahead and grab the scanner and we can see what the problem is.
(player grabs the scanner and scans the ship).
Companion
Luckily the ships mainframe doesn’t seem to damaged, so we can open the doors once we restart the power.
Companion
The bad news is the ships power switches have been messed up due to the crash, so you’ll need to put them back in the right order for me to restart the ship.
(Player fixed the switches)
Companion
Great! I can restart the ship now.
Companion
Oh… the ships way worse that I thought, everything’s offline so there’s no chance of us getting off this planet anytime soon.
Companion
Looks like we’ll need to fix the ship if we want any chance of getting home.
Companion
we have no other option apart from looking for some way to fix this ship on this planet.
(The companion heads to the door and the player leaves the ship)
Fade Out:
The End
This is my first time creating something like this so I had fun with it :D.
0 notes
moonsye · 8 years ago
Text
IK Controlling
While working on the Friendly AI me and Vitor thought it would be cool for the Alien to look at the player rather then straight in front of them, so I looked online and found the Unity has a system called IK which gives the rig weighted points of interest allowing me to move the head to the point of the player, here’s the code I used.
[RequireComponent(typeof(Animator))] public class IKControl : MonoBehaviour { public float range; protected Animator animator; public bool ikActive = false; public Transform rightHandObj = null; public Transform lookObj = null; void Start() { animator = GetComponent(); } //a callback for calculating IK void OnAnimatorIK() { if (animator) { //if the IK is active, set the position and rotation directly to the goal. if (ikActive) { // Set the look target position, if one has been assigned if (lookObj != null) { animator.SetLookAtWeight(1); animator.SetLookAtPosition(lookObj.position); } // Set the right hand target position and rotation, if one has been assigned if (rightHandObj != null) { animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1); animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1); animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandObj.position); animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandObj.rotation); } } //if the IK is not active, set the position and rotation of the hand and head back to the original position else { animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 0); animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 0); animator.SetLookAtWeight(0); } } } public void AssignLookObj ( Transform t ) { lookObj = t; } }
0 notes
moonsye · 8 years ago
Text
Friendly Aliens
So while working on the Enemy AI I began to work on friendly aliens the player would be able to talk to while they travel through the world, here’s a snippet of the code.
public class AlienRoaming : Interactibles { #region Fields private new Transform transform = null; // objects transform public Animator m_Animator = null; // animator private NavMeshAgent m_nav_mesh_agent = null; // nav mesh private Vector3 m_desired_position = Vector3.zero; // cache the next position public string[] m_dialog_keys = null; // keys to find the dialog on the file private Dialog m_dialog = null; // cache the dialog to display public Transform m_Location_object = null; // alien origin [SerializeField] private float m_min_movement, m_max_movement = 0f; // max and min movement [SerializeField] [Range(0, 50)] private float m_max_distance_from_object = 5f; // distance from the origin private float m_seconds_to_wait = 3f; // seconds that the alien will wait before moving again private int m_times_patroled = 0; // how many times from point to point private float m_timer_to_wait = 0f; // timer to count the seconds private float m_distance = 0f; // distance from the origin public IKControl m_IK_control = null; // ik control to animate the alien to look at the player #endregion #region Monobehaviour Functions void OnEnable() { // pause and resume funcs GameManager.OnPause += OnPause; GameManager.OnResume += OnResume; } void OnDisable() { // pause and resume funcs GameManager.OnPause -= OnPause; GameManager.OnResume -= OnResume; } void Awake() { // get references transform = GetComponent(); m_nav_mesh_agent = GetComponent(); } public void Start() { // setup the animator m_Animator.SetBool("Is_Attacking", false); m_Animator.SetBool("Is_Moving", true); // setting start position transform.position = m_Location_object.position; getNewDestination(); // grab all the dialogues by the keys List s = new List(); foreach ( string k in m_dialog_keys ) { s.Add ( DialogueHandler.GetDialogueByID ( k ) ); } // then generate the dialog with the speech m_dialog = new Dialog ( s.ToArray(), FontToDialog.FORREST ); } public void Update() { // check if the game is not running if(GameManager._Instance.MGameState != GameState.RUNNING) { return; } // calculate distance from the origin m_distance = Vector3.Distance ( m_Location_object.position, transform.position ); if (m_distance > m_max_distance_from_object) m_nav_mesh_agent.destination = m_Location_object.position; if (m_nav_mesh_agent.remainingDistance = 3) { m_Animator.SetBool("Is_Moving", false); m_timer_to_wait += Time.deltaTime; if (m_timer_to_wait >= m_seconds_to_wait) { m_timer_to_wait = 0f; m_times_patroled = 0; } return; } else { m_Animator.SetBool("Is_Moving", true); } m_times_patroled++; getNewDestination(); } } void OnTriggerEnter(Collider other) { if (other.gameObject == GameObject.FindGameObjectWithTag("Player")) { m_nav_mesh_agent.Stop(); m_Animator.SetBool("Is_Moving", false); // Debug.Log("Player Is Within Range"); // found the player, look at the player // ik stuff if (m_IK_control != null) { if ( m_IK_control.lookObj == null ) m_IK_control.AssignLookObj ( other.transform ); m_IK_control.ikActive = true; } } } void OnTriggerExit(Collider other) { if (other.gameObject == GameObject.FindGameObjectWithTag("Player")) { m_nav_mesh_agent.Resume(); m_Animator.SetBool("Is_Moving", true); //Debug.Log("Player Has Left Range"); // found the player, look at the player // ik stuff if (m_IK_control != null) { m_IK_control.ikActive = false; } } } #endregion #region Custom Functions public override InteractTypeReturn Interact(Transform player) { m_Animator.SetBool("Is_Moving", false); DialogManager._Instance.AddDialogToQueue(m_dialog); return InteractTypeReturn.TALKING; } //Generate New Position Randomly void getNewDestination() { m_nav_mesh_agent.destination = (transform.position + new Vector3(Random.Range(m_min_movement, m_max_movement), 0, Random.Range(m_min_movement, m_max_movement))); ; } //Assign New Position void getNewDestination(Vector3 pos) { setNewDestination(pos); } //Sets The Next Destination void setNewDestination(Vector3 pos) { m_desired_position = pos; } //Sets The Next Nav Mesh Destination void setNavMeshDestination() { m_nav_mesh_agent.destination = m_desired_position; } void OnDrawGizmos() { // draw the location object so it can be seen from the scene view if ( m_Location_object == null ) return; Gizmos.color = Color.red; Gizmos.DrawWireSphere ( m_Location_object.position, 1 ); } #endregion #region Pause and Resume Callbacks void OnPause() { // pause alien m_Animator.SetBool("Is_Moving", false); m_nav_mesh_agent.Stop(); } void OnResume() { // resume alien m_nav_mesh_agent.Resume(); if (m_nav_mesh_agent.remainingDistance > m_nav_mesh_agent.stoppingDistance) m_Animator.SetBool("Is_Moving", true); } #endregion }
0 notes
moonsye · 8 years ago
Text
Companion Code Fix
So after working on the Enemy AI I’ve realised how inefficient my original Companion code was so I decided to change it over to using States. Here’s some of the new code.
   #region MonoBehaviour Functions
   private void Awake ()    {        // singleton reference        if ( _instance == null)            _instance = this;        else            DestroyImmediate(this);
       followState = new FollowState(this);        scanState = new ScanState(this);        //switchAnimationState = new SwitchAnimationState(this);
       // get the nav mesh agent        navMeshAgent = GetComponent<NavMeshAgent>();
       // gather the transform of the companion        transform = GetComponent<Transform>();
       // get the collider        collider = GetComponent<Collider>();    }    void Start()    {        currentState = scanState;        //Debug.Log("Current State Is " + currentState);
       ResetCompanionStats();    }
// Update is called once per frame void Update ()    {        currentState.UpdateState();
       UpdateUI ();    }
   #endregion
   #region Custom Functions
   public void switchStateTrigger()    {        if(currentState == followState)        {            currentState = scanState;        }else if(currentState == scanState)        {            currentState = followState;        }    }
   public void CheckEnergy()    {        if ( m_energy <= 0f )        {            m_energy_animator.SetTrigger ( "Highlight" );        }        else if (m_energy > 0.05f)        {            m_energy_animator.SetTrigger ( "Normal" );        }
       // clamp the energy        m_energy = Mathf.Clamp ( m_energy, 0, m_max_energy );
       // update the UI        //UpdateUI();    }
   public void UpdateUI()    {        m_energy_step = (int) ( m_energy_bar.fillAmount / CustomHelpers.C_ONE_SIXTH );
       // health bar ui animation        if (m_energy != m_energy_step)        {            m_energy_cd_counter += GameManager._Instance.MGameTime;
           if (m_energy_cd_counter > m_energy_cd)            {                m_energy_cd_counter = 0f;
               if (m_energy > m_energy_step)                {                    m_energy_step++;                }                else if (m_energy < m_energy_step)                {                    m_energy_step--;                }
               // update the health bar UI                m_energy_bar.fillAmount = CustomHelpers.C_ONE_SIXTH * (float) m_energy_step;            }        }    }
   public void ResetCompanionStats()    {        m_energy = m_max_energy;
       CheckEnergy ( );    }
   public void DrainEnergy ( int amount )    {        //m_energy -= m_energy_rate * GameManager._Instance.MGameTime;        m_energy -= amount;
       CheckEnergy ( );    }
   public void RechargeEnergy ( int amount )    {        //m_energy += amount;        m_energy += amount;
       CheckEnergy ( );    }
   public void ForceCompanionPosition ( Vector3 pos )    {        transform.position = pos;    }
   public void EnableKeyComponent ( )    {        navMeshAgent.enabled = true;        collider.enabled = true;
       m_look_at.enabled = false;    }    #endregion
}
Defiantly made it more understandable and isn’t all over the place
0 notes
moonsye · 8 years ago
Text
Enemy Pattern
Update on the Enemy AI.
Here’s a snippet to the main code of the AI, this will be on each enemy and will control how they all work.
#region MonoBehaviour Functions
   private void Awake()    {        patrolState = new PatrolState(this, m_min_movement, m_max_movement);        alertState = new AlertState(this);        chaseState = new ChaseState(this);        attackState = new AttackState(this);        jumpAttackState = new JumpAttackState(this);        rotateAttackState = new RotateAttackState(this);        deathState = new DeathState(this);
       m_camera = Camera.main.GetComponent<Transform>();        transform = GetComponent<Transform>();        navMeshAgent = GetComponent<NavMeshAgent>();        rigidbody = GetComponent<Rigidbody>();    }
   // Use this for initialization    void Start()    {
       m_original_heal_bar_scale = m_health_bar.localScale.x;
       //enemySpawnManager = GetComponent<EnemySpawnManager>();
       animator.SetBool("Is_Attacking", false);        animator.SetBool("Is_Moving", true);        transform.position = spawnLocationObject.position;        currentState = patrolState;
       // assigning right animation clip to the animator
       //AnimatorOverrideController aoc = new AnimatorOverrideController();        //aoc.runtimeAnimatorController = animator.runtimeAnimatorController;
       //// switch between animations based on the states
       //switch (m_attacking_style)        //{        //    case AttackingStyle.CHASE_ATTACK:        //        aoc["Attacking"] = m_swiping;        //        break;        //    case AttackingStyle.JUMP_ATTACK:        //        Debug.Log("sabdjsd");        //        aoc["Attacking"] = m_jump_attack;        //        break;        //}
       //animator.runtimeAnimatorController = aoc;    }
   // Update is called once per frame    void Update()    {
       UpdateUI();
       if (currentState == deathState)            m_is_dead = true;
       Debug.Log("Current State Is " + currentState);
       if (m_health <= 0f)            currentState = deathState;
       currentState.UpdateState();
       //rigidbody.AddForce(transform.forward * m_jump_force);    }
   private void OnTriggerEnter(Collider other)    {        currentState.OnTriggerEnter(other);
       if (!check_first_collision)        {            CharacterControl c = other.GetComponent<CharacterControl>();            if (c != null)            {                characterControl = c;
               m_projectile.CreatePool();                m_projectile.m_Player = characterControl.MPlayerTransform;                check_first_collision = true;            }        }    }
   #endregion
   #region Custom Functions
   void SmoothLook(Vector3 newDirection)    {        transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(newDirection), Time.deltaTime);    }
   public void EnableCollisionBox()    {
       attackingObject.SetActive(true);
   }
   public void DisableCollisionBox()    {        //Debug.Log("This is being called");        attackingObject.SetActive(false);
   }
   public void ApplyJumpForce()    {        //rigidbody.AddForce(transform.forward * m_jump_force);
       Vector3 dir = chaseTarget.position - transform.position;        dir = dir.normalized;
       navMeshAgent.SetDestination(transform.position);    }
   public void EnterJumpAttackAnimation()    {        MJumpAttack = true;    }    public void ExitJumpAttackAnimation()    {        MJumpAttack = false;    }
   public void AssignSpawner(EnemySpawnManager spawner)    {        enemySpawnManager = spawner;    }
   public IEnumerator DeathWait()    {        yield return new WaitForSeconds(enemySpawnManager.cooldown);
       this.Recycle();
       ResetStats();        ResetState();    }
   public void RecycleEnemy()    {        StartCoroutine(DeathWait());    }
   void ResetState()    {        currentState = patrolState;    }
   void UpdateUI()    {        m_back_health_bar.LookAt(m_camera);
       float x = Mathf.Lerp(0, m_original_heal_bar_scale, GetHealthPercentage());        m_health_bar.localScale = new Vector3(x, m_health_bar.localScale.y, m_health_bar.localScale.z);    }
   #endregion
}
Some parts are commented out since I’m still working on them and aren’t working currently.
It’s still definitely way more easier to understand then my Companion code, might change that later.  
0 notes
moonsye · 8 years ago
Text
Questing!
So after having a conversation with the team we decided to tackle the Questing system that the player would follow in order to progress through the game.
Me and Vitor sat down together to code it so we could both learn how the system would work, here’s the code reference.
[System.Serializable] public class QuestDatabase {    #region Fields    public Quest            m_current_quest     = null;                 // current narrative quest that the player is doing    public Quest            m_next_quest        = null;                 // next quest on the queue for the player to do    public List<Quest>      m_quest_list        = new List<Quest>();    // list of all quests for the player to do    #endregion
   #region Constructor    public QuestDatabase()    {        m_quest_list = new List<Quest>();        m_quest_list = m_quest_list.OrderBy(o => o.m_Quest_id).ToList();    }    #endregion
   #region Custom Functions    public void UpdateDatabase()    {        UpdateQuest();        TriggerQuest();    }
   private void UpdateQuest ()    {        if ( m_current_quest == null )            return;
       switch ( m_current_quest.m_Quest_id )        {            case ( int ) NarrativeQuests.TUTORIAL_FIND_SCANNER:                // quest 00: find the scanner                if ( Bag._Instance.m_scanner != null )                {                    // quest complete                    FinishedQuest();                }                break;            case  ( int ) NarrativeQuests.TUTORIAL_FIX_SWITCHES:                // quest 01: fix the switches                CircuitBoardTutorial cb = m_current_quest.m_Game_Object.GetComponent<CircuitBoardTutorial>();
               if (cb.MHasFinished && cb.MHasStarted)                {
                   m_current_quest.m_Game_Object.SetActive(false);                    //Debug.Log(m_next_quest.m_Quest_id);                    FinishedQuest();                    //Debug.Log(m_next_quest.m_Quest_id);                }                break;        }    }
   private void TriggerQuest()    {        if (m_current_quest != null)            return;
       switch (m_next_quest.m_Quest_id)        {            case ( int ) NarrativeQuests.TUTORIAL_FIND_SCANNER:                if ( Gameplay._Instance.CanPlayerControlCharacter() &&                     Gameplay._Instance.CanPlayerControlCamera () &&                     ( DialogManager._Instance.MHasDialogLeft == false ) )                {                    TriggeringNextQuest();                }                break;            case ( int ) NarrativeQuests.TUTORIAL_FIX_SWITCHES:                if (Bag._Instance.m_scanner != null && (NotificationManager._Instance.MIsScreenPanelActive == false) && (!DialogManager._Instance.MHasDialogLeft) && (Gameplay._Instance.MHasUsedScanner == true))                {                    TriggeringNextQuest();                }                break;        }    }
   private void AssignQuest(Quest quest)    {    }
   private void FinishedQuest ()    {        // the current quest is now done        m_current_quest.m_Is_quest_done = true;        if (m_current_quest.m_Next_quest != null)        {            // if the quest is linked then we can load the next on the queue            m_current_quest = m_current_quest.m_Next_quest;        }        else        {            // there is no current quest, player might have to trigger it            m_current_quest = null;
           // hide the quest panel on the UI            QuestHandler._Instance.HideQuestPanel();        }    }
   private void TriggeringNextQuest()    {        // move on to the next quest        m_current_quest = m_next_quest;        Quest q = m_quest_list[m_current_quest.m_Quest_id + 1];        if (q != null)            m_next_quest = q;        else        {            // the player might have completed the game            // check for that        }
       // update the UI        QuestHandler._Instance.ShowQuestPanel();        QuestHandler._Instance.UpdateQuestPanelTitle(m_current_quest.m_Quest_name);    }
   public void SkipCurrentQuest()    {        // get the current quest and check if there is a quest assigned to it
       if (m_current_quest == null)            TriggeringNextQuest();
       FinishedQuest();    }    #endregion }
It didn’t take us long to code since we both did it together, and it works how we both wanted it to so that’s always a plus :D.
0 notes
moonsye · 8 years ago
Text
Working on Enemy AI
So after working on the Companion AI I began to work on Enemy AI using a different method to what I’ve used for the Companion.
I settled on using State Machine’s after watching a tutorial on Unity’s website, here’s a snippet from the code.
    public PatrolState(StatePatternEnemy statePatternEnemy, float min_movement, float max_movement)    {        enemy = statePatternEnemy;        m_min_movement = min_movement;        m_max_movement = max_movement;    }
   public void UpdateState()    {        Look();        Patrol();    }
   #region MonoBehaviour Functions
   public void OnTriggerEnter(Collider other)    {        Debug.Log("Something Has Entered The Trigger!");        if (other.gameObject.CompareTag("Player"))        {            m_has_collided = true;            CharacterControl c = other.GetComponent<CharacterControl>();
           if (c != null)            {                enemy.characterControl = c;                if (enemy.characterControl != null)                {                    if (enemy.characterControl.MIsCrouching)                        return;                }            }            ToAlertState();        }    }
   public void OnTriggerExit(Collider other)    {        if (other.gameObject.CompareTag("Player"))        {            enemy.characterControl = null;            m_has_collided = false;        }    }
After working through the tutorial I’ve found the code more understandable and way easier for me to create then my previous method. 
0 notes
moonsye · 8 years ago
Text
3D Models
Posting even more 3D work and this time its mine!
I’m not as good of a 3D artist as the others in my group so thankfully the things I’ve modelled are just props and/or weapons so they wont be seen that much compared to the other assets we have.
From left to right.
Stick, Leg Bone, (Alien) Walnut.
Tumblr media
Random Viles for potions and other things, 
Tumblr media
Since I’ve starting modelling again I wonder why I stopped, oh yeah the UVs.....
2 notes · View notes