Reputation: 17
I'm creating a 3th person game for a school project but I am having some trouble with collisions: I have a player with a camera as a child that has a sphere collider. When the camera collides with any scenery objects such as houses, it should zoom out. Once it leaves the collision situation it should return to its old position (its local y should be 4.5). Now I am having the following problem when standing still: the camera constantly leaves and enters the object's collider which causes it to keep zooming in and out. This results in a really glitchy looking camera movement. Is there any way to solve this problem?
I used the following code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamMovement : MonoBehaviour
{
public GameObject Parent;
//Checks if the camera collides with something
void OnTriggerStay(Collider other)
{
//When colliding, the camera moves up and back from the player object
transform.position += new Vector3(0, 0.2f, -0.2f);
}
void Update()
{
//makes sure the camera always looks at the player object
transform.LookAt(Parent.transform);
//Moves the camera back to the normal (local) position
if (transform.localPosition.y > 4.5f)
{
transform.position += new Vector3(0, Time.deltaTime * -4f, Time.deltaTime * 4f);
}
}
}
Footage of what it looks like when the camera collides with something: https://i.sstatic.net/pIn9n.jpg
Upvotes: 0
Views: 8252
Reputation: 4806
You need to check which collider is colliding with the camera collider, you could achieve this using a structure something like this in your OnColliderEnter(Collider other)
:
Collider playerCollider = GameObject.Fine("Player").GetComponent<Collider>();
if (!other == playerCollider)
{
//Do your zooming out.
}
Upvotes: 1
Reputation: 2157
Not sure if I understood what you want to achieve correctly but I'll give it a shot:
I think you should rather look into OnTriggerEnter
and OnTriggerExit
event so you can tell the Camera to move away when trigger is entered and move back when its exited.
public class CamMovement : MonoBehaviour
{
//using "parent" as variable name is not recommended since Transform class already contains a parent variable
[SerializeField]
private GameObject parentToLookAt;
[SerializeField]
private Vector3 localPositionOffset;
[Range(0.0f, 10.0f)]
[SerializeField]
private float transitionSpeed;
private Vector3 localPositionOnStart;
private bool applyOffset;
void Start()
{
localPositionOnStart = transform.localPosition;
applyOffset = false;
}
void Update()
{
//Makes sure the camera always looks at the player object
//You can also use: transform.LookAt(transform.parent);
transform.LookAt(parentToLookAt.transform);
//Moves the camera to the right local position (note that using Mathf.Lerp is not optimal performance-wise but if you want more info on this
//I recommend looking for further informations at https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/ )
if (applyOffset)
{
transform.localPosition = Mathf.Lerp(transform.localPosition, localPositionOnStart + localPositionOffset, transitionSpeed * Time.deltaTime);
}
else
{
transform.localPosition = Mathf.Lerp(transform.localPosition, localPositionOnStart, transitionSpeed * Time.deltaTime);
}
}
//Checks if the camera collides with something
void OnTriggerEnter(Collider other)
{
applyOffset = true;
}
//Checks if the camera stops colliding with something
void OnTriggerExit(Collider other)
{
applyOffset = false;
}
//You can also use this:
//void OnTriggerStay(Collider other)
//{
// applyOffset = true;
//}
// and set applyOffset to false at the end of the Update() method (OnTrigger events are called before Update each frame)
}
Two more things:
[SerializeField]
attribute to serialize a private variable (and therefor make it appear in the Inspector). I also added the [Range()] attribute which is useful when working with designers (they don't like raw numbers ;) )Upvotes: 0