Resident Evil/Silent Hill style combat

nathh

New member
Hi, I was wondering if anyone could give me some pointers in how to achieve a combat style similar to the classic Resident Evil or Silent Hill games.

Currently I'm using the Third Person Adventure movement type and using Cinemachine for my cameras. This is working great for general movement, the player walks in the direction relative to the camera.

However when firing weapons or aiming the character will always face directly upwards.

I would like the character to face the direction they are currently facing/moving when firing and aiming. I would also like to be able to use the target ability to auto-aim at enemies when holding the aim button.

I've tried (for testing purposes) switching to the psuedo3D and top down movement types with 'look in move direction' ticked but this does not fix the issue when either aiming or shooting without aiming. I've also tried turning off 'fire in look source direction' for the weapon but this doesn't seem to have any effect either.

Any help would be greatly appreciated.
 
Currently I have the use ability disabled with a state that enables it when the player holds the aim button. This is working, although the character still aims directly upwards each time.
 
Bit more progress, I stumbled across the 'Use Character Look Direction' tickbox under the Third Person Cinemachine view type on the camera controller. Now the character aims in the direction they're facing - which is great!

The final step would now be to have the player aim towards an enemy target when they're within range. I assume this is possible somehow? It seems the aim assist relies on the crosshair so I'm not sure that's the solution.
 
Think I have this pretty much working as intended now so I'll leave this here in case anyone else is looking for a solution in the future:

In addition to the previous steps mentioned-

I set the movement type to third person psuedo 3D

I added a rotate towards ability to the player.

I set the rotate towards target to an empty game object in the scene that I called 'RotateTowards_Target'

I wrote a short c# script which enables/disables the RotateTowards_Target game object and sets its transform to the nearest enemy that is in range (using tags for the enemies).

I used the state system to enable the rotate towards ability when the player is aiming.

-

Haven't tested this extensively yet but it seems to be functioning as expected. Will post back if I encounter any other problems, if not I'll mark as solved.
 
Right, almost there.

I'm trying to activate my 'RotateActive' state when the player is aiming. I have the following code (attached to an empty game object in the scene) which works if I remove all references to the Aim state (problem being that the character is constantly in the 'RotateActive' state when within range). I have been trying to add a check to see if the player is in the Aim state and if so execute the code under update().

Here's where I'm at, which currently doesn't do anything when its run :confused:

Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Opsive.Shared.StateSystem;
using Opsive.UltimateCharacterController.StateSystem;
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities.Items;

public class TargetClosest : MonoBehaviour
{
    public Transform targeter; // used to set the targeter position
    public GameObject targeterObject; // used to set targeter object so it can be made active/inactive
    public Transform player;
    public GameObject playerObject;
    public float interpolationPeriod = 0.1f;
    public float lockOnDistance = 10f;
    private UltimateCharacterLocomotion characterLocomotion;
    private State aimState;
    private float time = 0.0f;
    private GameObject target;
    private Transform targetpos;
    private float storedDistance;
    public GameObject FindClosestEnemy()
    {
        GameObject[] gos;
        gos = GameObject.FindGameObjectsWithTag("Enemy");
        GameObject closest = null;
        float distance = Mathf.Infinity;
        Vector3 position = player.position;
        foreach (GameObject go in gos)
        {
            Vector3 diff = go.transform.position - position;
            float curDistance = diff.sqrMagnitude;
            if (curDistance < distance)
            {
                closest = go;
                distance = curDistance;
                storedDistance = curDistance;
            }
        }
        return closest;
    }

    // Start is called before the first frame update
    void Start()
    {
        characterLocomotion = playerObject.GetComponent<UltimateCharacterLocomotion>();
        aimState = System.Array.Find(characterLocomotion.States, state => state.Name == "Aim");
    }

    // Update is called once per frame
    void Update()
    {
        if (aimState != null && aimState.Active)
        {
            time += Time.deltaTime;
            if (time >= interpolationPeriod)
            {
                time = 0.0f;
                target = FindClosestEnemy();
                if (storedDistance < lockOnDistance)
                {
                    targetpos = target.transform;
                    StateManager.SetState(playerObject, "RotateActive", true);
                    targeter.position = targetpos.position;
                }

                else StateManager.SetState(playerObject, "RotateActive", false);
            }
        }
    }
}


I'm sure I'm missing something simple. Any advice?
 
Ended up making an additional two states 'RotateActive' and 'RotateDeactive' one which sets the target to the targeter, the other that sets it to none.

I activate/deactivate these two states twice each in my distance check, once when a target is within range, and again when its not.

I then simply had to make an additional state called 'Aim' which enables/disables the RotateTowards ability. So the ability is active whenever you aim but the target value is only linked to the targerer object when within range.

Maybe a bit over complicated for the task but it works!

The state system is pretty ace :)
 
Glad you figured it out - this is exactly the kind of thing the state system was made for!
 
Top