freezing the y position of the camera in unity3d - c#

I am making a plat former game and I'm having a problem in the camera position of the game im imitating the camera movement of the 1st version of the super mario bros but every time I move my character the camera will go up until the character will disappear. How can I fix it?
public Transform playerPos;
public Transform rigthCamBoundary;
public Transform levelEnd;
Vector3 destination;
Vector3 velocity = Vector3.zero;
private void Start()
{
destination = Vector3.ClampMagnitude(levelEnd.position, 22.8f);
destination = new Vector3(destination.x, destination.y, 13.5f);
}
private void FixedUpdate()
{
if (Vector3.Distance(playerPos.position, rigthCamBoundary.position) < 13.7f)
transform.position = Vector3.SmoothDamp(transform.position, levelEnd.position, ref velocity, .14f, 8.5f);
}

To freeze the y-axis, get the y-axis value when the game runs. After using Vector3.SmoothDamp, change the y-axis to that variable you got before then apply it to your transform.
public Transform playerPos;
public Transform rigthCamBoundary;
public Transform levelEnd;
Vector3 destination;
Vector3 velocity = Vector3.zero;
float yPos;
private void Start()
{
destination = Vector3.ClampMagnitude(levelEnd.position, 22.8f);
destination = new Vector3(destination.x, destination.y, 13.5f);
//Get the default camera y pos
yPos = transform.position.y;
}
private void FixedUpdate()
{
if (Vector3.Distance(playerPos.position, rigthCamBoundary.position) < 13.7f)
{
Vector3 tempPos = Vector3.SmoothDamp(transform.position, levelEnd.position, ref velocity, .14f, 8.5f);
//Apply the default camera y pos
tempPos.y = yPos;
transform.position = tempPos;
}
}
Note that I don't know if this code is attached to the camera but this answer assumes it is. Otherwise the solution still remains the-same but you just have to change transform.position.y and transform.position to something else.

Related

Objects changed rotation jumps to it's original Unity3D

I made input joysticks for mobile game. One that moves the player and other one that changes it's rotation. Both are working fine but only problem is that when I change players rotation and release that joystick it jumps to it's original rotation. Here's my script:
public GameObject player;
private PlayerInput playerInput;
void Update()
{
Vector2 input = playerInput.actions["Move"].ReadValue<Vector2>();
Vector3 move = new Vector3(input.x, input.y, 0);
player.transform.position += move * speed * Time.deltaTime;
Vector2 look = playerInput.actions["Look"].ReadValue<Vector2>();
player.transform.rotation = Quaternion.LookRotation(Vector3.forward, look);
}
I typically solve this by ignoring rotation values of small magnitude and maintaining the last frame's orientation in said case. You might have to tune the threshold below to filter out the correct values.
public GameObject player;
private PlayerInput playerInput;
private Vector2 look;
void Update()
{
Vector2 input = playerInput.actions["Move"].ReadValue<Vector2>();
Vector3 move = new Vector3(input.x, input.y, 0);
player.transform.position += move * speed * Time.deltaTime;
var inputLook = playerInput.actions["Look"].ReadValue<Vector2>();
look = inputLook.magnitude > 0.1f ? inputLook : look;
player.transform.rotation = Quaternion.LookRotation(Vector3.forward, look);
}

Restricting cursor to a radius around my Player

I am currently working on an multiplayer shooter game. Basicly atm you play as a cube and you have your hand(red square) following the cursor ingame.
I want to restrict the cursor movement to a perfect circle around my player sprite.
See attached picture for clarification.
https://imgur.com/TLliade
Following script is attached to the "Hand" (red square).
public class Handscript : MonoBehaviour
{
void Update()
{
Cursor.visible = false;
Vector3 a = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
a.Set(a.x, a.y, transform.position.z);
transform.position = Vector3.Lerp(transform.position, a, 1f);
}
}
Now I want to restrict cursor movement inside my radius that is a public transform attached to my Player prefab like this:
//Hand radius
public float radius;
public Transform centerRadius;
I am hard stuck and new to coding overall and I could use a push in the right direction.
Basicly the same question is asked here if I am being to unclear:
https://answers.unity.com/questions/1439356/limit-mouse-movement-around-player.html
EDIT: My goal in the end is to have similar hand movement as in the legendary "Madness Interactive" game, found here:
https://www.newgrounds.com/portal/view/118826
EDIT2: It might be impossible to lock the cursor inside the radius circle. Is it possible to just have the GameObject "Hand" locked inside this radius?
EDIT3: This is the code I use and it works like a charm:
using System;
using UnityEngine;
public class Handscript : Photon.MonoBehaviour
{
[SerializeField] private GameObject Player2; //Drag your player game object here for its position
[SerializeField] private float radius; //Set radius here
public new PhotonView photonView; //Never mind this if its not a photon project
private void Start()
{
Cursor.visible = false;
}
void Update()
{
if (photonView.isMine) //Never mind this if statement if it isnt a photon project
{
Vector3 cursorPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
Vector3 playerPos = Player2.transform.position;
Vector3 playerToCursor = cursorPos - playerPos;
Vector3 dir = playerToCursor.normalized;
Vector3 cursorVector = dir * radius;
if (playerToCursor.magnitude < cursorVector.magnitude) // detect if mouse is in inner radius
cursorVector = playerToCursor;
transform.position = playerPos + cursorVector;
}
}
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
UnityEditor.Handles.DrawWireDisc(transform.parent.position, Vector3.back, radius); // draw radius
}
#endif
}
Get vector from the player to the cursor:
Vector3 playerToCursor = cursorPos - playerPos;
Normalize it to get the direction:
Vector3 dir = playerToCursor.normalized;
Multiply direction by your desired radius:
Vector3 cursorVector = dir * radius;
Add the cursor vector to the player position to get the final position:
Vector3 finalPos = playerPos + cursorVector;

How do I make my character run around the camera in third person?

I'm working on a third-person run-around game and there's a specific kind of movement I've wanted to achieve but I'm having trouble even imagining how it would work, let alone actually coding it.
Essentially, when holding left or right, I want the player to orbit the camera. Such a camera effect can be seen here. That's exactly what I want to achieve.
Here's my movement and camera code so far. I image I'll need to use the camera's Y rotation to achieve this but my tests haven't worked out. Any input would be appreciated!
Movement:
public int speed = 10;
public int rotationSpeed = 10;
public CharacterController cc;
Vector2 input;
Vector3 moveDir;
Vector3 lookDir;
Vector3 forward;
Transform camTransform;
public Transform model;
void Start () {
cc = GetComponent<CharacterController>();
camTransform = Camera.main.transform;
}
void GetInput() {
input.x = Input.GetAxisRaw("Horizontal");
input.y = Input.GetAxisRaw("Vertical");
}
void CalculateForward()
{
}
void Move()
{
moveDir.x = input.x;
moveDir.z = input.y;
if(moveDir.magnitude > 1)
{
moveDir.Normalize();
}
Vector3 rotatedDir = Camera.main.transform.TransformDirection(moveDir);
rotatedDir = new Vector3(rotatedDir.x, 0, rotatedDir.z);
rotatedDir = rotatedDir.normalized * moveDir.magnitude;
cc.Move(rotatedDir * speed * Time.deltaTime);
}
void ApplyGravity()
{
}
void FaceDir()
{
if (moveDir != Vector3.zero)
{
transform.rotation = Quaternion.Slerp(
transform.rotation,
Quaternion.LookRotation(-moveDir),
Time.deltaTime * rotationSpeed
);
}
}
private void FixedUpdate()
{
GetInput();
//ApplyGravity();
Move();
FaceDir();
ApplyGravity();
}
}
Camera:
[SerializeField]
private float distanceAway;
[SerializeField]
private float distanceUp;
[SerializeField]
private float smooth;
[SerializeField]
private Transform follow;
private Vector3 targetPosition;
private void Start()
{
follow = GameObject.FindWithTag("Player").transform;
}
private void LateUpdate()
{
targetPosition = follow.position + follow.up * distanceUp - follow.forward * distanceAway;
transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * smooth);
transform.LookAt(follow);
}
Movement around a circle is always in a direction tangential to the circle, so with each update you want to:
Set the Y rotation of the player to be looking directly at the Y axis of the camera
rotate the player 90 degrees left or right (depending on the direction you want to go)
move the player forward a distance that will depend on the speed with which you would like them to move
Remember it's impossible to traverse a circle perfectly because there are infinitely many points on a circle but this approach will approximate it well enough.

In Unity3D, what is the best way to offset the viewport with multiple resolutions so the player is always to the left edge?

I'm working on my latest project, which is a action sidescroller, primarily 2D but using a perspective camera for 3D effect. I've gotten the basics working - design, etc, and now fixing the camera so that it follows correctly. However, I'd like to keep the player on the left side of the viewport - not actually modifying the player's position, but the camera following an offset. I have it partially worked out, but it broke the moment I started playing around with other alternative resolutions - say, from web standard, standalone, to mobile devices. This is what I want to do:
This is my code attempt thus far. The camera itself works perfectly for basic up/down right scrolling, but when the resolution changes the player can vanish:
public Transform TrackTarget;
public float dampTime = 0.15f;
public bool Ready = false;
private Vector3 velocity = Vector3.zero;
private Vector3 TargetOffset = Vector3.zero;
void Start()
{
TargetOffset = new Vector3(16,0,0);
Vector3 point = TrackTarget.position + TargetOffset;
Vector3 Destination = new Vector3(point.x, transform.position.y, transform.position.x);
transform.position = Destination;
}
void FixedUpdate () {
if (Ready) {
if (TrackTarget)
{
Vector3 point = TrackTarget.position + TargetOffset;
Vector3 Destination = new Vector3(point.x, transform.position.y, transform.position.x);
transform.position = Vector3.SmoothDamp(transform.position, Destination, ref velocity, dampTime);
}
}
}
void LateUpdate()
{
if (Ready) {
Vector3 CameraPosition = transform.position;
CameraPosition.z = -30.00f;
transform.position = CameraPosition;
}
}
This may be helpful.
public class CameraController : MonoBehaviour {
public Transform target;
public float distance = 5;
public float heigt = 1;
public float width = 6;
public float damping = 5;
void Start()
{
Vector3 unicornPos = camera.WorldToViewportPoint(target.position);
width = camera.ViewportToWorldPoint(new Vector3(1, 1, camera.nearClipPlane)).x/3;
}
void LateUpdate () {
Vector3 wantedPosition = target.TransformPoint (width, heigt, -distance);
transform.position = Vector3.Lerp (transform.position, wantedPosition, Time.deltaTime * damping);
}
}

Accelerate and decelerate to finger position

I have a 3D object on Unity and what I want is simply move this object as soon as the user presses the screen. The problem is that it needs to accelerate first and then, when it is reaching the pressed position, it starts decelerating until it totally stops on that point.
I need this to work in a way that if the user moves his finger, the object will recalculate if it needs to accelerate/decelerate based on his current condition.
I tried this example but, it only works for acceleration and it also seems a little confusing. So, I was thinking if someone else have a better and simple idea to solve this. Can physics help with this? If so, how?
My code is in C#.
Using unity rigidbody system and simple calculate. This is using mouse position, you can change it to touch.
public class MyDragMove : MonoBehaviour {
public float speedDelta = 1.0f;
public float decelerate = 1.0f;
private bool startDrag;
private Vector3 prePos;
void Update () {
this.rigidbody.drag = decelerate; //Rigidbody system can set drag also. You can use it and remove this line.
if (Input.GetKeyDown (KeyCode.Mouse0)) {
prePos = Input.mousePosition;
startDrag = true;
}
if(Input.GetKeyUp(KeyCode.Mouse0))
startDrag = false;
if(startDrag)
ForceCalculate();
}
void ForceCalculate()
{
Vector3 curPos = Input.mousePosition;
Vector3 dir = curPos - prePos;
float dist = dir.magnitude;
float v = dist / Time.deltaTime;
this.rigidbody.AddForce (dir.normalized * v * Time.deltaTime * speedDelta);
prePos = curPos;
}
}
or just use SmoothDamp toward last position.
public class MyDragMove : MonoBehaviour {
public float speedDelta = 1.0f;
public float maxSpeed = 5.0f;
public Vector3 v;
private Vector3 prePos;
void Update () {
if(Input.GetKey(KeyCode.Mouse0))
prePos = Input.mousePosition;
TowardTarget ();
}
void TowardTarget()
{
Vector3 targetPos = Camera.main.ScreenToWorldPoint (new Vector3(prePos.x, prePos.y, 10f)); //Assume your camera's z is -10 and cube's z is 0
transform.position = Vector3.SmoothDamp (transform.position, targetPos, ref v, speedDelta, maxSpeed);
}
}

Categories

Resources