Camera between mouse and object. top down 2d. c#
Context
I am working on a top down 2d shooter. The player moves with WASD, and always faces the mouse.
I need a camera that stays at the mid point between the player and the cursor, unless that mid point is past a certain radius away from the player. The camera cant leave that radius.
Question
I am trying to c# code a camera that does 3 things:
(I've included an image below to better explain what I mean)
Stay directly at the mid point of the player object and the mouse. figure A
The Camera can not go past a certain distance / radius away from the player. (even if mid point between player and camera exceeds that distance) figure B
Keeps track of the distance between the player object and camera object. (so I can use that variable later)
I have exhausted my google-fu, and looked through so many script examples, and I keep coming up just short.
Any help would be greatly appreciated. Thankyou.
have you done any coding i am working in unity now & i have done what you need but i don't know what do you mean by " faces the mouse cursor " & i don't know how to get the cursor position without click so i added a target.transform ins$$anonymous$$d to let you get the idea hope you or any one can replace the target.transform position with the cursor position here is the code :
using UnityEngine; using System.Collections;
public class $$anonymous$$ov : $$anonymous$$onoBehaviour
{
float midpointX;
float midpointY;
// if you place the target object in unity more than 6 camera will do nothing
public float limit = 6 ;.
public Camera cam;
public Transform target;
void Update ()
{
midpointX = transform.position.x + target.transform.position.x / 2;
midpointY = transform.position.y + target.transform.position.y / 2;
if (target.position.x <= limit & target.position.y <= limit)
{
cam.transform.position = new Vector3 (midpointX,midpointY,-10);
}
}
}
Hi, thanks for your reply. I will take a look at the code later. I have got a fully working JS version, doing exactly what I need, I've posted it as an answer to my original question.
Answer by Adam_Benko · Dec 12, 2018 at 09:06 PM
Here is a c# version of the code: All credit goes to @MD_Reptile :)
public class CameraControll : MonoBehaviour
{
public Transform Parent; // Whatever you want the camera locked to
public Transform Obj; // The object to place the camera on
public float Radius = 4.5f;
float Dist;
Vector3 MousePos1, MousePos2, ScreenMouse, MouseOffset;
public void Update()
{
MousePos1 = Input.mousePosition;
// the below line assumes this script is attached to a camera object
ScreenMouse = GetComponent<Camera>().ScreenToWorldPoint(new Vector3(MousePos1.x, MousePos1.y, Obj.position.z - GetComponent<Camera>().transform.position.z));
MouseOffset = ScreenMouse - Parent.position;
MousePos2 = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, -transform.position.z));
//Obj.position.y = ((MousePos2.y - Parent.position.y) / 2.0) + Parent.position.y;
//Obj.position.x = ((MousePos2.x - Parent.position.x) / 2.0) + Parent.position.x;
Obj.position = new Vector3((MousePos2.x - Parent.position.x) / 2.0f + Parent.position.x, (MousePos2.y - Parent.position.y) / 2.0f + Parent.position.y, Obj.position.z);
Dist = Vector2.Distance(new Vector2(Obj.position.x, Obj.position.y), new Vector2(Parent.position.x, Parent.position.y));
if (Dist > Radius)
{
var norm = MouseOffset.normalized;
//Obj.position.x = norm.x * Radius + Parent.position.x;
//Obj.position.y = norm.y * Radius + Parent.position.y;
Obj.position = new Vector3(norm.x * Radius + Parent.position.x, norm.y * Radius + Parent.position.y, Obj.position.z);
}
}
}
$$anonymous$$arked as answered for visibility.
Credit to @$$anonymous$$D_Reptile (who's reply I can't mark as an answer)
It works, but its all glitchy. It shakes a little when i move the character and glitches out when i move it around
This was a nice start, but I've done some improvements....:
public class CameraControlMain2D : MonoBehaviour {
[SerializeField] private Transform playerTransform;
private float radius = 30f;
private float smoothTime = 0.3F;
private Vector3 velocity = Vector3.zero;
public void Update() {
Vector3 mousePosition = MousePosition.GetMouseWorldPosition();
Vector3 newPosition = new Vector3(
(mousePosition.x - playerTransform.position.x) / 2f + playerTransform.position.x,
(mousePosition.y - playerTransform.position.y) / 2f + playerTransform.position.y,
transform.position.z
);
float dist = Vector2.Distance(
new Vector2(newPosition.x, newPosition.y),
new Vector2(playerTransform.position.x, playerTransform.position.y)
);
if (dist > radius) {
Vector3 mouseOffset = mousePosition - playerTransform.position;
var norm = mouseOffset.normalized;
newPosition = new Vector3(
norm.x * radius + playerTransform.position.x,
norm.y * radius + playerTransform.position.y,
transform.position.z
);
}
transform.position = Vector3.SmoothDamp(transform.position, newPosition, ref velocity, smoothTime);
}
}
public class MousePosition {
// Get Mouse Position in World with Z = 0f
public static Vector3 GetMouseWorldPosition() {
Vector3 vec = GetMouseWorldPositionWithZ(Input.mousePosition, Camera.main);
vec.z = 0f;
return vec;
}
public static Vector3 GetMouseWorldPositionWithZ(Vector3 screenPosition, Camera worldCamera) {
Vector3 worldPosition = worldCamera.ScreenToWorldPoint(screenPosition);
return worldPosition;
}
}
Answer by vProject · Feb 29, 2016 at 05:22 PM
Posting this here for anyone looking for this sort of thing in the future.
This works exactly as shown in the pictures, It's JS though.
#pragma strict
var Parent : Transform; // Whatever you want to camera locked to
var Obj : Transform; // The object to place the camera on
var Radius = 4.5;
var Dist : float;
var MousePos1 : Vector3;
var MousePos2 : Vector3;
var ScreenMouse : Vector3;
var MouseOffset : Vector3;
function Update() {
MousePos1 = Input.mousePosition;
ScreenMouse = GetComponent.<Camera>().main.ScreenToWorldPoint(Vector3(MousePos1.x, MousePos1.y, Obj.position.z-GetComponent.<Camera>().main.transform.position.z));
MouseOffset = ScreenMouse - Parent.position;
MousePos2 = Camera.main.ScreenToWorldPoint(Vector3(Input.mousePosition.x, Input.mousePosition.y, -transform.position.z));
Obj.position.y = ((MousePos2.y - Parent.position.y)/2.0)+Parent.position.y;
Obj.position.x = ((MousePos2.x - Parent.position.x)/2.0)+Parent.position.x;
Dist = Vector2.Distance(Vector2(Obj.position.x, Obj.position.y), Vector2(Parent.position.x, Parent.position.y));
if(Dist > Radius){
var norm = MouseOffset.normalized;
Obj.position.x = norm.x*Radius + Parent.position.x;
Obj.position.y = norm.y*Radius + Parent.position.y;
}
}
Is there any reason I can only find this script in JS? I'm trying to use C#, but everywhere I find something like this everyone uses JS.
UNTESTED C# CONVERSION:
public class CamScript : $$anonymous$$onoBehaviour
{
Transform Parent; // Whatever you want to camera locked to
Transform Obj; // The object to place the camera on
float Radius = 4.5f;
float Dist;
Vector3 $$anonymous$$ousePos1, $$anonymous$$ousePos2, Screen$$anonymous$$ouse, $$anonymous$$ouseOffset;
public void Update()
{
$$anonymous$$ousePos1 = Input.mousePosition;
// the below line assumes this script is attached to a camera object
Screen$$anonymous$$ouse = GetComponent<Camera>().ScreenToWorldPoint(new Vector3($$anonymous$$ousePos1.x, $$anonymous$$ousePos1.y, Obj.position.z - GetComponent<Camera>().transform.position.z));
$$anonymous$$ouseOffset = Screen$$anonymous$$ouse - Parent.position;
$$anonymous$$ousePos2 = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, -transform.position.z));
//Obj.position.y = (($$anonymous$$ousePos2.y - Parent.position.y) / 2.0) + Parent.position.y;
//Obj.position.x = (($$anonymous$$ousePos2.x - Parent.position.x) / 2.0) + Parent.position.x;
Obj.position = new Vector3(($$anonymous$$ousePos2.x - Parent.position.x) / 2.0f + Parent.position.x, ($$anonymous$$ousePos2.y - Parent.position.y) / 2.0f + Parent.position.y, Obj.position.z);
Dist = Vector2.Distance(new Vector2(Obj.position.x, Obj.position.y), new Vector2(Parent.position.x, Parent.position.y));
if (Dist > Radius)
{
var norm = $$anonymous$$ouseOffset.normalized;
//Obj.position.x = norm.x * Radius + Parent.position.x;
//Obj.position.y = norm.y * Radius + Parent.position.y;
Obj.position = new Vector3(norm.x * Radius + Parent.position.x, norm.y * Radius + Parent.position.y, Obj.position.z);
}
}
}
Answer by charlessylvander · Oct 02, 2020 at 08:40 AM
@vProject check this out!
https://youtu.be/LFe017d-S58,@vProject I found a really helpful video on this. It is actually a lot simpler than you think!
thank you so much! I've searched high and low but couldn't find the answer. I know this thread is old but I just had to say thank you
Answer by boURiNEtte · Dec 27, 2016 at 08:10 AM
Hi I just began to port an old unfinished project on Flash to Unity a few days ago. It's 2D topdown too. I did find a way to make a similar kind of camera script (but simpler).
My Camera and my Player aren't parent nor child from each other. Works fine for the meantime.
Here's the script in UnityScript(js): followplayer.js attached to the camera.
#pragma strict
private var player:GameObject;
private var mousePosition:Vector2;
private var playerPosition:Vector2;
function Start () {
player = GameObject.FindWithTag("Player");
}
function Update ():void {
mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
playerPosition = player.transform.position;
SmoothFollow_Mouse(mousePosition, playerPosition);
}
function SmoothFollow_Mouse(a:Vector2, b:Vector2):void {
var c:Vector2 = (a + b)/2;
transform.position.x = (b.x + c.x)/2;
transform.position.y = (b.y + c.y)/2;
}
Answer by osybear · Dec 13, 2017 at 02:57 PM
Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);
Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
float rayLength;
if (groundPlane.Raycast(cameraRay, out rayLength))
{
Vector3 pointToLook = cameraRay.GetPoint(rayLength);
Vector3 NewPos = (gameObject.transform.position + pointToLook) / 2;
NewPos = new Vector3(NewPos.x, 10f, NewPos.z - 3.5f);
playerCam.transform.position = NewPos;
}
My camera is angled by 70* in the x and it works as expected.
Your answer

Follow this Question
Related Questions
Need help with camera in top down shooter 0 Answers
Cinemachine 2D LookAt 0 Answers
Rotate camera and player with mouse 2d top-down shooter in C# 1 Answer
Top Down Camera View Problem 1 Answer
Take screenshot with no lags Android 0 Answers