Mars Base Sandbox, MGS5-Like Reticle and Aiming, Movement Issues

Hello! Here’s my current sandbox, meant to be a Mars military outpost:

I’ve implemented an MGS5-like reticle system, where a ray is cast from the player’s eyes (later a gun barrel) and the intended target, splitting the reticle into ‘where you’re aiming’ and ‘where you’re going to actually hit.’ I’ve also expanded upon @Morgrhim 's camera code (Possible variation on Camera) adding different offsets for the camera to be in depending on player state, like crouching and aiming:

However, I’m having second thoughts about sticking with Unity’s built in Third Person Controller setup. It’s rigidbody based, which disallows for much of the fine controls that a Character Controller allows you, and introduces issues like players flying upwards through the air after going up a ramp or clumsily bouncing their way down them. I’m likely going to just go ahead and write my own custom Third Person script using the Character Controller and adapt it to the Mecanim system later.

CameraArm.cs
//
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Util;

// TODO: Fix camera clipping through geometry
// TODO: Refactor how aim offsets are selected/changed

public class CameraArm : MonoBehaviour {

//Partially stolen from https://community.gamedev.tv/t/possible-variation-on-camera/24331
//Thanks to Morgrhim!

public Vector3 Pivot;

[SerializeField] Vector3 DefaultOffset; // Offset while not aiming or crouching
[SerializeField] Vector3 CrouchOffset; // Offset while crouching
[SerializeField] Vector3 AimOffset; // Offset while aiming
[SerializeField] Vector3 CrouchAimOffset; // Offset while aiming and crouching

public bool Flip = false;

private Vector2 rotation;

private string TargetTag = "Player";
private GameObject pl;

private Camera m_Cam;

public enum Offset
{
    Default,
    Crouch,
    Aim,
    CrouchAim
}

private Offset CurrentOffset = Offset.Default;

void Start () {
    pl = GameObject.FindGameObjectWithTag(TargetTag);

    m_Cam = Camera.main;
    UpdateOffset();
}


void LateUpdate () {
    //TODO: Decouple input

    if (Input.GetAxis("Crouch") >= 1)
    {
        SetOffsetType(Offset.Crouch);
        if (Input.GetAxis("ADS") >= 1)
        {
            // crouching and aiming
            SetOffsetType(Offset.CrouchAim);
        }
    }
    else if (Input.GetAxis("ADS") >= 1)
        SetOffsetType(Offset.Aim);
    else
        SetOffsetType(Offset.Default);

    if (Input.GetKeyUp(KeyCode.V))
        Flip = !Flip;

    transform.position = pl.transform.position + Pivot;
    m_Cam.transform.localPosition = Utility.Vector3TimeLerp(m_Cam.transform.localPosition, UpdateOffset(), .001f, Time.deltaTime);

    rotation.x += Input.GetAxis("Mouse X");
    rotation.y -= Input.GetAxis("Mouse Y");

    rotation.y = ClampAngle(rotation.y, -70f, 70f);

    transform.rotation = Quaternion.Euler(rotation.y, rotation.x, 0f);
}

Vector3 UpdateOffset()
{
    Vector3 offset = Vector3.zero;

    switch (CurrentOffset)
    {
        case Offset.Aim:
            offset = AimOffset;
            break;
        case Offset.Crouch:
            offset = CrouchOffset;
            break;
        case Offset.CrouchAim:
            offset = CrouchAimOffset;
            break;
        default:
            offset = DefaultOffset;
            break;
    }

    if (Flip)
    {
        offset.x = -offset.x;
    }

    return offset;
}

public void SetOffsetType(Offset offset)
{
    CurrentOffset = offset;
}

float ClampAngle(float angle, float min, float max)
{
    if (angle < -360F)
        angle += 360F;
    if (angle > 360F)
        angle -= 360F;
    return Mathf.Clamp(angle, min, max);
}
}
1 Like

It’s looking awesome :smiley: really good work

Privacy & Terms