I am trying tio replicate the Dark souls like Target Lock in my game using Cinemachine. I actually coded my own targeting and it works well and good as it’s quite simple as a Transform.LookAt , but I need the goodies of Cinemachine like Camera Collision Detection, which is much more complex.
Is it a good idea to modify the camera manually when it is controlled by a Cinemachine brain or should I try to implement my targeting logic using Cinemachine. If so, I’m quite lost as how to look at a target while staying behind the player, essentially keeping both of them in frame.
When the CinemachineBrain is controlling the camera, then it will override anything you try to do manually to it. The way to control the camera manually within the context of Cinemachine is to create a virtual camera with “Do Nothing” in Aim and Body (i.e. no procedural motion), and then control its transform and lens manually.
For your other question, I would try using a FreeLook that follows the player but looks at a CinemachineTragetGroup that contains the player. Use the GroupComposer in Aim for all three rigs. When an enemy target enters the scene, add it to the target group. Then, the vcam will try to keep both the player and the enemy on screen. Remove the enemy from the target group when you’re done with it.
This partially solved my problem, the only thing I need now is to lock the camera on the back of the player.
What do you think can be the best way to achieve that?
ok, you have it set to SimpleFollow. I assume you then want to rotate the player so that it’s facing the same direction as the camera, thus putting the camera behind the player and not changing the camera aim, right?
If so, then you can try adding this extension to your freeLook (drop it in the project, then select it from the “Extensions” dropdown in the vcam inspector).
using UnityEngine;
using Cinemachine;
using Cinemachine.Utility;
/// <summary>
/// Rotate the Follow Target to look along the camera forward axis
/// </summary>
[SaveDuringPlay] [AddComponentMenu("")] // Hide in menu
public class RotateTargetToMatch : CinemachineExtension
{
public bool m_YRotationOnly = true;
protected override void PostPipelineStageCallback(
CinemachineVirtualCameraBase vcam,
CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
{
if (stage == CinemachineCore.Stage.Aim)
{
var follow = VirtualCamera.Follow;
if (follow != null)
{
Vector3 fwd = state.RawOrientation * Vector3.forward;
if (m_YRotationOnly)
fwd = fwd.ProjectOntoPlane(state.ReferenceUp);
follow.rotation = Quaternion.LookRotation(fwd, state.ReferenceUp);
}
}
}
}
Thank you again but I think I didn’t exaplain thinks in the right way. i want the camera the always face the back of the player withour using the mouse to rotate the camera which is not happening when I’m locking on a target even if I’m using Group Composer .
I think what he wants is exactly how dark souls Lock On system works , in which the camera always stays behind the player,following him, but looks at target, in such a way that the player and target are both in the frame. Essentially
The camera is placed behind the player by an offset and stays there.
The camera must face the player’s back at all times.
The camera must Look at a target from behind the player.
The main thing that’s confusing me is that you’re using a FreeLook. The FreeLook allows the camera to rotate around the player, using the mouse.
If you want the player to always look away from the camera, then attach the extension I gave. That will force the player to always face away from the camera, by rotating the player to match, leaving full control of the camera to the user.
So, one question. If you’ve “locked on” to a target, and the user rotates the camera to be in-between the player and the target, what is supposed to happen?
Free look : Player moves in the forward direction of the camera and the camera is free look. The user can control the camera with the Right Anlaog stick .
*Locked On : Player is always between Camera and target . The Camera should look at the target while staying behind the player, so that both the player and the target are in the frame. The camera’s forward direction is dependent on the player. The user cannot control the camera directly in this mode.
Dark souls works like this. The video I linked in the Original Post is what it looks like in action.
I think what’s confusing you is the use of free look that, as you said, is meant to allow the user to rotate the camera using the mouse while we want the camera to stay focused on both target.
For this issue I’m thinking about creating a virtual camera in a fixed position and toggle this camera when we’re locking in a target.
He cannot. The camera is Locked onto the target at all times. He has to leave the “Locked on” mode to control the camera manually . The right analog stick is useless in this mode.
Never personally played Dark Souls but for my instance if you are running away from a target after you locked on it I just switch back to free look mode.
ok, then this looks like a case of 2 vcams: a freeLook for normal mode, and a “locked” vcam for locked-to-target mode.
The FreeLook mode seems to be a normal FreeLook on the Player, no target group.
The Locked mode sounds like a simple vcam with Transposer and GroupComposer on a group containing player and target. Use the group as the LookAt target, and the player as the follow target. Use a Lock to target with World Up binding mode, and set the offset to something interesting. If you like, you can have a script that dynamically adjusts the offset (within a reasonable range) so that the user can vary the point of view a little.
Enable/disable the appropriate vcams when you change mode, and CM will do a smooth blend between them. Make sure you enable the “inherit position” checkboxes on the vcams.
Hard to respond without knowing what you’re seeing that’s wrong.
You probably need to check “inherit position” here and on the FreeLook also.
Right now you’ve got the group composer set up to zoom/dolly in/out to maintain group screen size. Probably you don’t want that. Disable that feature by setting the Framing mode to Dolly Only, and the Max dolly in/out to 0.