How to move 2D Object within camera view boundary - c#

I have a scene that my camera doesn't follow my player. When player reaches the end of camera I want player to can't go further (out of camera view). How can I do this?
My codes for movement
public class PlayerBlueController : MonoBehaviour {
public float speed;
private float x;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void FixedUpdate () {
x = Input.GetAxis ("Horizontal") / 100 * speed;
transform.Translate (x,0,0);
}
}
As you can see from this. It gets out of camera's view.

I noticed you used a Collider2D. You should be using Rigidbody2D.MovePosition instead of transform.Translate or you'll likely run into issues when transform.Translate is used.
1.Take the final move position and convert it to new position in ViewPortPoint with Camera.main.WorldToViewportPoint
2.Apply a limit with Mathf.Clamp to the result in #1.
3.Convert the ViewPortPoint back to world point with Camera.main.ViewportToWorldPoint.
4.Finally, move it with Rigidbody2D.MovePosition.
The code below is modified from this answer to include restriction to screen boundary.
Move without Rigidbody:
Use only if collision and physics are NOT required:
public float speed = 100;
public Transform obj;
public void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
//Move only if we actually pressed something
if ((h > 0 || v > 0) || (h < 0 || v < 0))
{
Vector3 tempVect = new Vector3(h, v, 0);
tempVect = tempVect.normalized * speed * Time.deltaTime;
Vector3 newPos = obj.transform.position + tempVect;
checkBoundary(newPos);
}
}
void checkBoundary(Vector3 newPos)
{
//Convert to camera view point
Vector3 camViewPoint = Camera.main.WorldToViewportPoint(newPos);
//Apply limit
camViewPoint.x = Mathf.Clamp(camViewPoint.x, 0.04f, 0.96f);
camViewPoint.y = Mathf.Clamp(camViewPoint.y, 0.07f, 0.93f);
//Convert to world point then apply result to the target object
obj.position = Camera.main.ViewportToWorldPoint(camViewPoint);
}
Move Object with Rigidbody2D:
Use if collision and physics are required:
public float speed = 100;
public Rigidbody2D rb;
public void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
//Move only if we actually pressed something
if ((h > 0 || v > 0) || (h < 0 || v < 0))
{
Vector3 tempVect = new Vector3(h, v, 0);
tempVect = tempVect.normalized * speed * Time.deltaTime;
//rb.MovePosition(rb.transform.position + tempVect);
Vector3 newPos = rb.transform.position + tempVect;
checkBoundary(newPos);
}
}
void checkBoundary(Vector3 newPos)
{
//Convert to camera view point
Vector3 camViewPoint = Camera.main.WorldToViewportPoint(newPos);
//Apply limit
camViewPoint.x = Mathf.Clamp(camViewPoint.x, 0.04f, 0.96f);
camViewPoint.y = Mathf.Clamp(camViewPoint.y, 0.07f, 0.93f);
//Convert to world point then apply result to the target object
Vector3 finalPos = Camera.main.ViewportToWorldPoint(camViewPoint);
rb.MovePosition(finalPos);
}

image not respond .
but you can check player location
x = Input.GetAxis ("Horizontal") / 100 * speed;
if(gameobject.transform.x > someValue)
x=0
gameobject will be OBJECT in scene that u attach class to it.
another way is place 2 empty gameobject with collider as invisibleWall and get collider to player

Possible solution is:
1.Get the coordinates of your screen cornes (top left, top right, bottom left, bottom right). You can get this coordinates using Screen.height and Screen.width.
2.Convert this coordinates using the camera you need with Camera.ScreenToWorldPoint.
3.Get your player coordinates and check that they are inside the rect which is formed by 4 coordinates of the screen corners.

You need to limit your transform's position based on the edges of the camera. Here is an answer describing the different coordinate systems in unity
You're probably looking to do something like this:
float xMin = Camera.main.ViewportToWorldPoint(Vector3.zero).x;
float xMax = Camera.main.ViewportToWorldPoint(Vector3.one).x;
Vector3 currentPos = transform.position;
float dx = Input.GetAxis ("Horizontal") / 100 * speed;
Vector3 desiredPos = new Vector3(currentPos.x + dx, currentPos.y, currentPos.z);
Vector3 realPos = desiredPos;
if(desiredPos.x > xMax)
realPos.x = xMax;
else if(desiredPos.x < xMin)
realPos.x = xMin;
transform.position = realPos;
Read up here for more info on ViewportToWorldPoint(), it's extremely useful to become comfortable with the different coordinate spaces and how you can convert between them.

Related

Move Character from point A to B smoothly unity

So, Hey guys I am new to unity. I have a small doubt. I have a player who is a child of the topcube in a 3 stackcube placed upon eachother.
These cubes have a target position to move once the user clicks on them.
Like imagine there are 3 points in my world. POINT A with location coordinates as(0,0,1),POINT B with (0,0,2),POINT C with (0,0,3) and the 3 stack cube is place on (0,0,0) with the player attached as a child to topcube in that 3stackcube.
All these points(A,B,C) has a script called targetpoint with a variable bool isFilled(default as false) in them which becomes true when one of the cube reaches to its target position.
Further im checking whenever the cubes reaches their target position make isFilled true and check to see if there is a child attached if yes get the animator of the child and trigger jump animation. The jump animation is an inplace animation.
So I want to programmatically move my character +1 towards the direction he is facing (if he is facing z move + 1 in z, if x move +1 in x like this)when the cube he is attached reached its target position while also playing jump animation.
I did a code. it doesnt seem to be working. And sorry for huge paragraphs. Im totally new to coding and asking doubts. Any help will be helpful thanks.
[SerializeField] public List<targetpoint> waypoints;
[SerializeField] float moveSpeed = 2f;
[SerializeField] AudioClip[] surferSounds;
[SerializeField] GameObject particleToPlay;
int waypointIndex = 0;
float t;
//Cached Reference
AudioSource audioSource;
//State
public bool move = false;
void Start()
{
transform.position = this.transform.position;
t = 0f;
}
void FixedUpdate()
{
if (move == true)
{
MoveTarget();
}
}
void MoveTarget()
{
//Time.timeScale = 0.1f;
if (waypointIndex <= waypoints.Count - 1)
{
var targetPosition = waypoints[waypointIndex].transform.position;
transform.position = Vector3.MoveTowards(transform.position, targetPosition, moveSpeed * Time.deltaTime);
if (transform.position == targetPosition)
{
//Debug.Log(t);
if (waypoints[waypointIndex].isFilled == false)
{
waypoints[waypointIndex].isFilled = true;
AudioClip clip = surferSounds[UnityEngine.Random.Range(0, surferSounds.Length)];
var storeToDestroy = Instantiate(particleToPlay, targetPosition, Quaternion.identity);
Destroy(storeToDestroy , 5f);
audioSource.PlayOneShot(clip);
move = false;
}
else if(waypoints[waypointIndex].isFilled == true)
{
waypointIndex++;
targetPosition = waypoints[waypointIndex].transform.position;
transform.position = Vector3.MoveTowards(transform.position, targetPosition, moveSpeed * Time.deltaTime);
}
if (this.gameObject.transform.childCount > 0)
{
var storeChild = gameObject.transform.GetChild(1).gameObject;
StartCoroutine(GravityAndJump(storeChild,storeChild.transform.position+1*transform.forward,1f));
}
else
{
return;
}
}
}
}
IEnumerator GravityAndJump(GameObject child, Vector3 newPosition , float time)
{
var elapsedTime = 0f;
var startingPosition = child.transform.position;
while(elapsedTime < time)
{
child.GetComponent<Animator>().SetTrigger("shouldJump?");
child.transform.position = Vector3.Lerp(startingPosition, newPosition, (elapsedTime / time));
elapsedTime += Time.deltaTime;
yield return null;
}
//storeChild.GetComponent<Animator>().SetFloat("JumpSpeed", 1f);
//yield return new WaitForSeconds(1f);
//gameObject.GetComponentInChildren<Rigidbody>().useGravity = true;
}
}
So I want to programmatically move my character +1 towards the direction he is facing (if he is facing z move + 1 in z, if x move +1 in x like this)
You can get the forward direction for a GameObject using with transform.forward you can use this to calculate target position in front of the GameObject.
Set target position some distance in front of the transform
targetPosition = transform.position + (transform.forward * distance);
Move towards target position at some speed.
transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * followSpeed);
Determining arrival to targetPosition
When it comes to determining if transform has arrive to target destination you should measure the distance instead of comparing that the vectors are the same.
So replace this:
if (transform.position == targetPosition){}
With something like this:
if(Vector3.Distance(transform.position, targetPosition) < .001f){
transform.position = targetPosition;
}
Unless you strictly set two vectors to same values it's likely that they will never be considered equal due to how floating point numbers work.

Unity3D - C# 360 Orbital Camera Controller (Gimbal Lock Issue)

I have a stationary cube in my scene that I'm orbiting a camera around. I have my MainCamera nested under a GameObject that I'm calling 'OrbitalCamera'.
I setup the script so that a click (or tap) and drag will rotate the camera around the object in space so it feels like you're rotating the cube (ie: if I click the top of a face on the cube, and pull down, I'm rotating the X value) but you'll actually be rotating the camera.
For the most part, my script works. However, after rotating the Y so much, the camera is upside down and the X gets inverted. Here's my script:
public class OrbitalCamera : MonoBehaviour {
public bool cameraEnabled;
[SerializeField] private float touchSensitivity;
[SerializeField] private float scrollSensitivity;
[SerializeField] private float orbitDampening;
protected Transform xFormCamera;
protected Transform xFormParent;
protected Vector3 localRotation;
protected float cameraDistance;
void Start () {
cameraEnabled = true;
xFormCamera = transform;
xFormParent = transform.parent;
cameraDistance = transform.position.z * -1;
}
void LateUpdate () {
if (cameraEnabled) {
// TODO:: FIX PROBLEM WHERE WHEN CAMERA IS ROTATED TO BE UPSIDEDOWN, CONTROLS GET INVERSED
if (Input.GetMouseButton(0)) {
if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0) {
localRotation.x += Input.GetAxis("Mouse X") * touchSensitivity;
localRotation.y -= Input.GetAxis("Mouse Y") * touchSensitivity;
}
}
}
Quaternion qt = Quaternion.Euler(localRotation.y, localRotation.x, 0);
xFormParent.rotation = Quaternion.Lerp(xFormParent.rotation, qt, Time.deltaTime * orbitDampening);
}
}
Is there a good method to achieve this type of 360 camera? I'd like dragging from right to left to always move the camera left and dragging left to right to always move the camera right -- no matter how the camera is oriented.
Perhaps you could clamp the above/below pan at 89 degrees?
I recently helped a friend make a mouse gimbal, and found allowing freedom beyond 89 degrees was problematic and unnecessary. It seems like your application is the same, at least for one of the two planes.
In your LateUpdate() call, you could perhaps add:
localRotation.x += Input.GetAxis("Mouse X") * touchSensitivity;
localRotation.x = Clamp(localRotation.x);
Then, of course, create your clamp function, which should be fairly straight forward:
float Clamp(float val) // prevent values from ~90 - ~270
{
int lowVal = 89;
int highVal = 271;
int midVal = 180;
if (val > lowVal & val < highVal)
{
if (val > midVal) val = highVal;
else val = lowVal;
}
return val;
}
A slightly different application, but I'm sure you can see how I've set this up: I apply rotation in two steps. Step 1 - a simple Rotate() call, Step 2 - clamping some/all of the rotation:
using UnityEngine;
public class MouseGimbal : MonoBehaviour
{
[SerializeField] [Range(0,89)] float maxRotationDegrees = 10.0f; // At 90+ gimbal oddities must be dealt with.
[SerializeField] bool ClampToMaxRotationDegrees = true; // Disable for free rotation.
[SerializeField] float rotationSpeed = 10.0f;
const float fullArc = 360.0f;
const float halfArc = 180.0f;
const float nullArc = 0.0f;
void Update () { Tilt(); }
void Tilt()
{
// Apply the 'pre-clamp' rotation (rotation-Z and rotation-X from X & Y of mouse, respectively).
if (maxRotationDegrees > 0) { SimpleRotation(GetMouseInput()); }
// Clamp rotation to maxRotationDegrees.
if (ClampToMaxRotationDegrees) { ClampRotation(transform.rotation.eulerAngles); }
}
void ClampRotation(Vector3 tempEulers)
{
tempEulers.x = ClampPlane(tempEulers.x);
tempEulers.z = ClampPlane(tempEulers.z);
tempEulers.y = nullArc; // ClampPlane(tempEulers.y); // *See GIST note below...
transform.rotation = Quaternion.Euler(tempEulers);
///Debug.Log(tempEulers);
}
float ClampPlane(float plane)
{
if (OkayLow(plane) || OkayHigh(plane)) DoNothing(); // Plane 'in range'.
else if (BadLow(plane)) plane = Mathf.Clamp(plane, nullArc, maxRotationDegrees);
else if (BadHigh(plane)) plane = Mathf.Clamp(plane, fullArc - maxRotationDegrees, fullArc);
else Debug.LogWarning("WARN: invalid plane condition");
return plane;
}
Vector2 GetMouseInput()
{
Vector2 mouseXY;
mouseXY.x = -Input.GetAxis("Mouse X"); // MouseX -> rotZ.
mouseXY.y = Input.GetAxis("Mouse Y"); // MouseY -> rotX.
return mouseXY;
}
void SimpleRotation(Vector2 mouseXY)
{
Vector3 rotation = Vector3.zero;
rotation.x = mouseXY.y * Time.deltaTime * rotationSpeed;
rotation.z = mouseXY.x * Time.deltaTime * rotationSpeed;
transform.Rotate(rotation, Space.Self);
}
void DoNothing() { }
bool OkayHigh(float test) { return (test >= fullArc - maxRotationDegrees && test <= fullArc); }
bool OkayLow(float test) { return (test >= nullArc && test <= maxRotationDegrees); }
bool BadHigh(float test) { return (test > halfArc && !OkayHigh(test)); }
bool BadLow(float test) { return (test < halfArc && !OkayLow(test)); }
}
When I developed an orbital camera, I created 3 objects:
- x_axis (rotate with vertical mouse moviment)
- y_axis (rotate with horizontal mouse moviment)
- camera (look_at object) (translated Vector3(0,0,-10))

How can i prevent from moving the camera view under the terrain?

I'm using this mouseorbit script attached to a camera.
The problem is when i move the camera with the mouse and rotating it so the camera is under the terrain.
I want that when it get to the terrain height then stop don't move down i mean don't get to this view under the character maximum to be in the terrain height..
To stop on terrain height i mean something like that when it's getting to this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseOrbit : MonoBehaviour
{
/* These variables are what tell the camera how its going to function by
* setting the viewing target, collision layers, and other properties
* such as distance and viewing angles */
public Transform viewTarget;
public LayerMask collisionLayers;
public float distance = 6.0f;
public float distanceSpeed = 150.0f;
public float collisionOffset = 0.3f;
public float minDistance = 4.0f;
public float maxDistance = 12.0f;
public float height = 1.5f;
public float horizontalRotationSpeed = 250.0f;
public float verticalRotationSpeed = 150.0f;
public float rotationDampening = 0.75f;
public float minVerticalAngle = -60.0f;
public float maxVerticalAngle = 60.0f;
public bool useRMBToAim = false;
/* These variables are meant to store values given by the script and
* not the user */
private float h, v, smoothDistance;
private Vector3 newPosition;
private Quaternion newRotation, smoothRotation;
private Transform cameraTransform;
/* This is where we initialize our script */
void Start()
{
Initialize();
}
/* This is where we set our private variables, check for null errors,
* and anything else that needs to be called once during startup */
void Initialize()
{
h = this.transform.eulerAngles.x;
v = this.transform.eulerAngles.y;
cameraTransform = this.transform;
smoothDistance = distance;
NullErrorCheck();
}
/* We check for null errors or warnings and notify the user to fix them */
void NullErrorCheck()
{
if (!viewTarget)
{
Debug.LogError("Please make sure to assign a view target!");
Debug.Break();
}
if (collisionLayers == 0)
{
Debug.LogWarning("Make sure to set the collision layers to the layers the camera should collide with!");
}
}
/* This is where we do all our camera updates. This is where the camera
* gets all of its functionality. From setting the position and rotation,
* to adjusting the camera to avoid geometry clipping */
void LateUpdate()
{
if (!viewTarget)
return;
/* We check for right mouse button functionality, set the rotation
* angles, and lock the mouse cursor */
if (!useRMBToAim)
{
/* Check to make sure the game isn't paused and lock the mouse cursor*/
if (Time.timeScale > 0.0f)
Cursor.lockState = CursorLockMode.Locked;
h += Input.GetAxis("Mouse X") * horizontalRotationSpeed * Time.deltaTime;
v -= Input.GetAxis("Mouse Y") * verticalRotationSpeed * Time.deltaTime;
h = ClampAngle(h, -360.0f, 360.0f);
v = ClampAngle(v, minVerticalAngle, maxVerticalAngle);
newRotation = Quaternion.Euler(v, h, 0.0f);
}
else
{
if (Input.GetMouseButton(1))
{
/* Check to make sure the game isn't paused and lock the mouse cursor */
if (Time.timeScale > 0.0f)
Cursor.lockState = CursorLockMode.Locked;
h += Input.GetAxis("Mouse X") * horizontalRotationSpeed * Time.deltaTime;
v -= Input.GetAxis("Mouse Y") * verticalRotationSpeed * Time.deltaTime;
h = ClampAngle(h, -360.0f, 360.0f);
v = ClampAngle(v, minVerticalAngle, maxVerticalAngle);
newRotation = Quaternion.Euler(v, h, 0.0f);
}
else
{
Cursor.lockState = CursorLockMode.Confined;
}
}
/* We set the distance by moving the mouse wheel and use a custom
* growth function as the time value for linear interpolation */
distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 10, minDistance, maxDistance);
smoothDistance = Mathf.Lerp(smoothDistance, distance, TimeSignature(distanceSpeed));
/*We give the rotation some smoothing for a nicer effect */
smoothRotation = Quaternion.Slerp(smoothRotation, newRotation, TimeSignature((1 / rotationDampening) * 100.0f));
newPosition = viewTarget.position;
newPosition += smoothRotation * new Vector3(0.0f, height, -smoothDistance);
/* Calls the function to adjust the camera position to avoid clipping */
CheckSphere();
smoothRotation.eulerAngles = new Vector3(smoothRotation.eulerAngles.x, smoothRotation.eulerAngles.y, 0.0f);
cameraTransform.position = newPosition;
cameraTransform.rotation = smoothRotation;
}
/* This is where the camera checks for a collsion hit within a specified radius,
* and then moves the camera above the location it hit with an offset value */
void CheckSphere()
{
/* Add height to our spherecast origin */
Vector3 tmpVect = viewTarget.position;
tmpVect.y += height;
RaycastHit hit;
/* Get the direction from the camera position to the origin */
Vector3 dir = (newPosition - tmpVect).normalized;
/* Check a radius for collision hits and then set the new position for
* the camera */
if (Physics.SphereCast(tmpVect, 0.3f, dir, out hit, distance, collisionLayers))
{
newPosition = hit.point + (hit.normal * collisionOffset);
}
}
/* Keeps the angles values within their specificed minimum and maximum
* inputs while at the same time putting the values back to 0 if they
* go outside of the 360 degree range */
private float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
/* This is our custom logistic growth time signature with speed as input */
private float TimeSignature(float speed)
{
return 1.0f / (1.0f + 80.0f * Mathf.Exp(-speed * 0.02f));
}
}
It looks like the script i grabbed already handles terrain collision... i just need to make sure to set the collision layers on it to include the terrain. But not sure how to do it.
What i tried:
I added now a new layer in the inspector called it Terrain.
Then in the hierarchy on the Terrain i change it's layer to terrain.
Also in the script i selected Terrain. But it's still not working.
In the screenshot the top is the inspector of the camera with the script selected in Collision Layers Terrain.
In the bottom the terrain inspector selected Terrain as :Layer
Many answers to this question.
But here's my take on it since I am fairly certain this solution is interesting compared to all solutions you will find online related to unity 3rd person controllers.
Abstract
In Unity, you could take the usual approach of having an empty object and having that be the parent of the camera, etc... But what people in the industry would typically do is use a mathematical formula called Spherical coordinates.
This, by far, is the best approach for 3rd person controllers from my experience and its the most elegant and beautiful approach. All you need to do after implementing this approach, is shoot a ray from the camera down a meter, and if it detects anything, then change a single value in your spherical coordinates formula which would make the sphere around the player smaller which gives the effect of collision
Implementation
Here's a snippet of code which shows a single function needed to create the spherical coordinates formula.
private Vector3 sphericalCoordinates()
{
float m = distanceFromPlayer;
v = mouseY;
h = mouseX;
x = m * Mathf.Sin(v) * Mathf.Cos(h);
z = m * Mathf.Sin(v) * Mathf.Sin(h);
y = m * Mathf.Cos(v);
Vector3 pos = new Vector3(x, y, z);
return pos;
}
m = magnitude.
You can think of this as the radius from the sphere, this is what you change to give the collision effect.
I later use this snippet to bind the player with the camera in trigger.
[NOTE: very unclean code, I just wanted to show you a basic concept, definitely make it cleaner later]
Vector3 getCamRotWORLD()
{
Vector3 camRotWORLD = new Vector3(0, transform.rotation.eulerAngles.y, 0);
return camRotWORLD;
}
void adjustPlayerRot()
{
if (Input.GetKey(KeyCode.W))
{
player.transform.rotation = Quaternion.Euler(player.transform.rotation.x, getCamRotWORLD().y, player.transform.rotation.z);
player.transform.Translate(0, 0, playerScript.speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.A))
{
player.transform.rotation = Quaternion.Euler(player.transform.rotation.x, getCamRotWORLD().y - 90, player.transform.rotation.z);
player.transform.Translate(0, 0, playerScript.speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.S))
{
player.transform.rotation = Quaternion.Euler(player.transform.rotation.x, getCamRotWORLD().y - 180, player.transform.rotation.z);
player.transform.Translate(0, 0, playerScript.speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.D))
{
player.transform.rotation = Quaternion.Euler(player.transform.rotation.x, getCamRotWORLD().y + 90, player.transform.rotation.z);
player.transform.Translate(0, 0, playerScript.speed * Time.deltaTime);
}
}
Here's how my update looks like in case you really would like to snatch the implementation instead of trying to experiment with it yourself.
private void Update()
{
mouseX -= Input.GetAxis("Mouse X") * (sensitivity * Time.deltaTime);
mouseY -= Input.GetAxis("Mouse Y") * (sensitivity * Time.deltaTime);
playerCam.transform.LookAt(player.transform);
playerCam.transform.position = new Vector3(
sphericalCoordinates().x + player.transform.position.x,
sphericalCoordinates().y,
sphericalCoordinates().z + player.transform.position.z
);
}

Unity avoiding obstacles with pathfinding c#

I have a simple project which includes pathfinding with obstacle avoidance. Now, I have void Steer which steers the object around since the path is not straight. then I have void AvoidObstacles which has raycast and the obstacle avoidance part basically.
Whenever the object steers, it calls the AvoidObstacles function. The problem now is, at the start, whenever it hasn't call in the Steer function yet, because it is a straigh line, it passes through the object not avoiding it.
Here are some of the codes used:
public Vector3 Steer(Vector3 target, bool bFinalPoint = false)
{
//Calculate the directional vector from the current position towards the target point
Vector3 desiredVelocity = (target - transform.position);
float dist = desiredVelocity.magnitude;
AvoidObstacles(ref desiredVelocity);
//Normalise the desired Velocity
desiredVelocity.Normalize();
//Calculate the velocity according to the speed
if (bFinalPoint && dist < 10.0f)
desiredVelocity *= (curSpeed * (dist / 10.0f));
else
desiredVelocity *= curSpeed;
//Calculate the force Vector
Vector3 steeringForce = desiredVelocity - velocity;
Vector3 acceleration = steeringForce / mass;
return acceleration;
}
here is the other one
public void AvoidObstacles(ref Vector3 desiredVelocity)
{
RaycastHit hit;
Vector3 leftRay = transform.position;
Vector3 rightRay = transform.position;
//leftRay.x -= 2;
//rightRay.x += 2;
Debug.DrawLine(transform.position,(transform.forward * 5) + transform.position,Color.green);
if(Physics.Raycast(transform.position, transform.forward,out hit, minimumDistToAvoid))
{
Debug.DrawLine(transform.position,(transform.forward * 10) + transform.position,Color.red);
if(hit.transform != transform)
{
//dir += hit.normal * 50;
//Get the normal of the hit point to calculate the new direction
Vector3 hitNormal = hit.normal;
hitNormal.y = 0.0f; //Don't want to move in Y-Space
//Get the new directional vector by adding force to vehicle's current forward vector
desiredVelocity = transform.forward + hitNormal * force;
}
}
}
and here is my update
void Update ()
{
//Unify the speed
curSpeed = speed * Time.deltaTime;
targetPoint = path.GetPoint(curPathIndex);
//If reach the radius within the path then move to next point in the path
if(Vector3.Distance(transform.position, targetPoint) < path.Radius)
{
//Don't move the vehicle if path is finished
if (curPathIndex < pathLength - 1)
curPathIndex ++;
else if (isLooping)
curPathIndex = 0;
else
return;
}
//Move the vehicle until the end point is reached in the path
if (curPathIndex >= pathLength )
return;
//Calculate the next Velocity towards the path
if(curPathIndex >= pathLength - 1 && !isLooping)
velocity += Steer(targetPoint, true);
else
velocity += Steer(targetPoint);
transform.position += velocity; //Move the vehicle according to the velocity
transform.rotation = Quaternion.LookRotation(velocity); //Rotate the vehicle towards the desired Velocity
//AvoidObstacles(ref Vector3 desiredVelocity);
dir.Normalize();
}
Maybe someone can help me out buy letting me know how can I call the avoidobstacle function outside of steer? Maybe in update or start perhaps.
I can't really use other algorithms, just this one right here. TIA

Keeping my object from rolling out of the screen

I am using the tilt function on a phone to control an object to roll left and right. I do not want it roll anything beyond the screen width.
As in the simple illustration below, the dotted lines represent the width of the screen. The 'O' is the object and the Max signs indicate the maximum point the object is allowed to roll to.
Max--------O--------Max
But currently using my code, the object still rolls out of the screen. Also tried testing both height n width and ended up the same result where the object rolls out of the screen. Please advice what I am doing wrong. Thank you.
public float speed = 10.0F;
void Update()
{
Vector3 dir = Vector3.zero;
dir.x = Input.acceleration.x;
if (dir.sqrMagnitude > 1)
dir.Normalize();
dir *= Time.deltaTime;
if (!(Mathf.Round(dir.x) > Mathf.Round(Screen.width/2)) || !(Mathf.Round(dir.x) < -Mathf.Round(Screen.width/2)))
{
transform.Translate(dir * speed);
}
}
**Updated
public float speed = 10.0F;
void Update()
{
Vector3 dir = Vector3.zero;
dir.x = Input.acceleration.x;
if (dir.sqrMagnitude > 1)
dir.Normalize();
dir *= Time.deltaTime;
//transform.Translate(dir * speed);
if (transform.position.x < 0)
{
transform.position = new Vector3(0, this.transform.position.y, this.transform.position.z);
}
else if (transform.position.x > Screen.width)
{
transform.position = new Vector3(Screen.width, this.transform.position.y, this.transform.position.z);
}
else
{
transform.Translate(dir * speed);
}
}
I think thereare several ways you can go about checking the transfomrs position.
first off if you were using a 2d camera you could use a method like
leftBounds = Camera.x - (Camera.pixelWidth/2);
however because ortho camera angles are not set at any particulare size at x distace from camera they are hard to calculate.
i have seen some instances were coliders on the camera just outside the render rand were placed as camera children
adding a colision mask to only affect the appropriate game object would be best.

Categories

Resources