What a great overview of some good core mechanics!

I would just like to say this has been an excellent course. Has got me back into Unity development again, I cannot put it down!. Previously focused on mobile games couple of years back but this has sparked a new interest and I am now trying to turn this into something great. (Its keeping busy for sure) I have even started to learn Blender to create my own models too. Easier than I thought for Low Poly.

The topics covered have been great. I have been developing software for over 20 years. Had a few aspects to resolve along the way. But has been a great journey of discovery and inspiration. This has given new insight into how things can be done well within Unity.

I have expanded this with some new actions: Reload, land mines and even different unit types with limited ammo and weapon types per unit. Have also implemented droppable and collectable items. (ammo/health etc)

I have expanded to support as many players as I want and choose Human or AI. Entertaining to watch AI vs AI. (This area needs a bit needs a bit more TLC).

I have also added a HUD to move to the selected unit. That was tricky to with CineMachine, but got there eventually.

Would be good to see

  • Possible lowered and raised levels for grid system (e.g. basement / bunkers / stairs)
  • Fog of war
    -Many more I cannot think of right now…

The possibilities for this are endless.

Great work and well worth it. Cant wait to see/follow more from Code Monkey.

Looking forward to full integration of the Hex Grid now :smile:

That’s great to hear, those are great additions.

I’m curious, how did you implement the Item pickup? Did you do it on “touch” and automatically pick up when a character enters that grid position? Or using the Interact action?

I’m glad you’re enjoying the course! Thanks!

I have implemented a couple of ways.

  1. Collider trigger on entering a grid square, so fairly simple approach, where collectables sit on a given layer mask

Using a CollectionSystem I monitor the OnAnyUnitMOvedGridPosition event.
Then it detects the type assigned (Ammo/health etc) and assigns to the unit.

The downside of the way is only one collectable per grid position.

  1. On another version, I have items scattered randomly (not on grid positions) and the unit picks this up when they are near (although may change this as not 100% sold on this way).

I have since seen what you had started to implement e.g. the standard “Minecraft Style” inventory approach. This may be be more efficient as you can choose what to pick up or not. Although maybe breaks the standard “Action” based approach.

Can you share a video and code for ‘HUD to move to the selected unit’? I am intreaged.

Hi,

Can you share a video and code for ‘HUD to move to the selected unit’? I am intreaged.

My UI is very simple, Just a grid layout on a panel with buttons.
(I am getting all my function in place before I make things pretty with Blender! )

Not sure how to easily get a video… and its quite late, but I can share code for now.

A new script “HUDUnits” monitors the OnUnitSpawned/OnUnitDead events. To add the the UI container dynamically.
And other events as needed, when a unit takes damage etc…

On the UI Click handler of each HUD Unit UI element. I start a camera transition using Cinemachine.

The trickier bit, I think is the cinemachine blend/detect aspect.

Essentially, I have just extended the CameraManager class.
And because its using cinemachine, it even points the direction the unit it pointing.

What this also allows is that when its the next turn, we can auto select the first unit and bring into view, whether human or AI.

public class CameraManager : MonoBehaviour
{
    [SerializeField] private GameObject actionCameraGameObject;
    [SerializeField] private GameObject targetCameraGameObject;

    [SerializeField] private Cinemachine.CinemachineVirtualCamera cinemachineVirtualCamera;
    [SerializeField] private Cinemachine.CinemachineVirtualCamera cinemachineVirtualCameraTarget;

   private Cinemachine.CinemachineBrain cinemachineBrain;

    private bool IsMovingToTarget = false;
    private bool HasBlendStarted = false;

   .......

private void Start()
    {

        cinemachineBrain = Cinemachine.CinemachineCore.Instance.GetActiveBrain(0);

        if(cinemachineBrain==null)
        {
            Debug.LogError("Could not find active CinemachineBrain");
        }

..............................
    }


private void Update()
    {
        if (!IsMovingToTarget) { return; }

        if(cinemachineBrain.IsLive(cinemachineVirtualCameraTarget) && !HasBlendStarted && cinemachineBrain.ActiveBlend!=null)
        {
            Debug.Log("BLEND:" + cinemachineBrain.ActiveBlend);

            HasBlendStarted = true;
            Debug.Log("Blend started...");
            return;
        }
        else if(HasBlendStarted && cinemachineBrain.ActiveBlend==null) //blending has ended
        {
            Debug.Log("Blend Done!");
            HasBlendStarted = false;
            IsMovingToTarget = false;

            SetCameraFollowLookAt(cinemachineVirtualCameraTarget, cinemachineVirtualCamera, cameraControllerTransform);
            HideTargetCamera();
        }

    }


    private void SetCameraFollowLookAt(Cinemachine.CinemachineVirtualCamera activeVCam, Cinemachine.CinemachineVirtualCamera InactiveVCam,Transform newTransform)
    {
        Transform activeVCamTransformFollow = activeVCam.Follow;
        Transform activeVCamTransformLookAt = activeVCam.LookAt;

        cameraControllerTransform.position = activeVCam.Follow.position;
        cameraControllerTransform.rotation = activeVCam.Follow.rotation;
    }

   ///This is called from the UI click, to move to the selected unit, smooth transtion
    public void TransitionCamera(Transform position)
    {
        if(targetCameraGameObject!=null)
        {

            CinemachineTransposer transposer = cinemachineVirtualCamera.GetCinemachineComponent<CinemachineTransposer>();
            Vector3 followOffset = transposer.m_FollowOffset;

            CinemachineTransposer targetTransposer = cinemachineVirtualCameraTarget.GetCinemachineComponent<CinemachineTransposer>();
            targetTransposer.m_FollowOffset = followOffset;

            //set new camera lookat/follow targets
            cinemachineVirtualCameraTarget.Follow = position;
            cinemachineVirtualCameraTarget.LookAt = position;

            IsMovingToTarget = true;
            ShowTargetCamera();
         
        }

    }



Hopefully this helps for now, took me ages googling Cinemachine. Cinemachine does not have a great event when when blending ends. The important bit for me, was setting the new position of the camera controller transform to allow normal camera movement after blending, but from the new position. Took me all evening to this working end-to-end, so not too bad in the end.

Regards,
Paul

1 Like

Thanks. I’ll integrate into my ui. I have simply teleported the main camera to selected unit for now. This should look nicer.

Privacy & Terms