REN QINXIN's Metaverse
Survive Junchoka -
The Third Person Survival game
1 Brief Intro
Survive Junchoka is a 3D project where the main character has to effortfully dodge attacks from regenerative monsters to survive. There are bonuses and bases for the player to gain the extra scores and super power. The player can attack the monster when gets the super power.
Demo:
Project Deliverable
PC Game
Game Design
3D Design
Timeline
Apr 2022
1 month
Tools Used
Unity
Blender
Shader Tool
Team
This is a personal project.
My Contributions
-
Designed and implemented the FSM AI systems of both the player and monsters' behaviour patterns.
-
Brainstormed the game mechanics and level design, and implemented them independently.
-
Adjusted the lighting settings using Shader and rendering pipeline for better visual effects.
2 Design of the characters' FSM
Monster FSM Design
White Box test of monster's FSM
To let the enemy patrol the player, the finite state machine (FSM) is written. The enemy will chase the player if the player is within the patrol distance, otherwise, it will continue the patrol.
The gif shows the white box test of the enemy behaviour pattern, the overall animation of the enemy is based on this fsm.
monster's animation setting
Therefore, according to the white box, the animation of the enemy is set as the figure above. It has 3 major statuses: attack, walk and idle.
The enemy will start patroling automatically, and will start chasing the player if the player is too close to it. If the player is within the attack range, the monster will attack the player. If the player get the superpower and attack the monster, it will die.
Sample Code of animation control
private void Animation() { AnimatorStateInfo stateInfo = m_animator.GetCurrentAnimatorStateInfo(0); //Idle if (stateInfo.fullPathHash == Animator.StringToHash("Base Layer.Idle") && !m_animator.IsInTransition(0)) { m_animator.SetBool("Idle", false); m_timer -= Time.deltaTime; if (m_timer > 0) { return; } //start tracking if (Vector3.Distance(m_transform.position, target.transform.position) m_dis) { m_timer = 1; navMeshAgent.SetDestination(target.transform.position); m_animator.SetBool("Walk", true); } else m_animator.SetBool("Attack", true); } else { navMeshAgent.ResetPath(); m_animator.SetBool("Idle", true); } } //Walk if (stateInfo.fullPathHash == Animator.StringToHash("Base Layer.WalkFWD") && !m_animator.IsInTransition(0)) { m_animator.SetBool("Walk", false); m_timer -= Time.deltaTime; if (m_timer < 0) { navMeshAgent.SetDestination(target.transform.position); m_timer = 1; } MoveTo(); if (/*Vector3.Distance(m_transform.position, target.transform.position) 10f) { navMeshAgent.ResetPath(); m_animator.SetBool("Idle", true); } } //Attack if (stateInfo.fullPathHash == Animator.StringToHash("Base Layer.Attack01") && !m_animator.IsInTransition(0)) { RotateTo(); m_animator.SetBool("Attack", false); IsAttack = false; if (stateInfo.normalizedTime >= 1.0f) { IsAttack = true; m_animator.SetBool("Idle", true); m_timer = 1; } } if (EnemyHealthSystem.isDead) { m_animator.SetTrigger("Dead"); //destory the collider Destroy(this.GetComponent()); navMeshAgent.speed = 0; if (stateInfo.normalizedTime >= 1.0f) { //OnDeath() } } }
3 Shader for highlight settings
Highlight demo
It can be seen that the bases (tent) and bonuses (potion) are highlighting in the game, to give the player hints.
To achieve the highlight effect, Shader is used.
-
Rim effect is added to the 'emission'. The rim of the objects are used to represent the highlight range.
-
Sin function is added to the '_Time' to achieve the dynamic shining. The light of objects will follow the sin wave.
-
Use the ScreenPointToRay function to emit a ray to get the layers of intersecting objects, set the highlighting effect if it is the corresponding layer, and unhighlight the previous objects.
Sample Code of the highlight Shader
float3 viewDir = normalize(UnityWorldSpaceViewDir(IN.worldPos)); float3 normal = normalize(IN.worldNormal); float rimPower = pow(1 - saturate(dot(normal, viewDir)), _RimPow); fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; o.Emission = _Highlighted * rimPower * _RimColor * lerp(0.5,1,(sin(_Time.x*_RimColorSpeed)+1)/2);
4 Design Details
One page Design Doc
In Survive Junchoka, the player needs to control the main character Junchoka to move and hide from the monster’ attack. There are game props including the ‘bases’ and ‘bonuses’. The base would give the player a superpower once touched by the player. Then the monsters will seek for the touched base and a new monster will randomly generate in the plain when monsters touch the base. Scores/ HP will be added when touched by the player.