Set player's boundary within sphere - c#

I want to restrict player movement in the sphere, the schematic diagram show as below. If player movement is out of range, then restrict player to sphere max radius range.
How can I write C# code to implement it, like this?
These are my current steps:
Create 3D sphere
Create C# code append to sphere object
My code so far:
public Transform player;
void update(){
Vector3 pos = player.position;
}

I don't know how you calculate your player`s position but before assigning the new position to the player you should check and see if the move is eligible by
checking the new position distance form the center of the sphere
//so calculate your player`s position
//before moving it then assign it to a variable named NewPosition
//then we check and see if we can make this move then we make it
//this way you don't have to make your player suddenly stop or move it
//back to the bounds manually
if( Vector3.Distance(sphereGameObject.transform.position, NewPosition)< radius)
{
//player is in bounds and clear to move
SetThePlayerNewPosition();
}

What #Milad suggested is right but also include the fact you won't be able to "slide" on the sphere border if your movement vector even slightly goes outside the sphere :
(sorry for the crappy graphic skills...)
What you can do if you want to be able to "slide" on the sphere interior surface is get the angle formed between the player position and the X vector and then apply this angle with the :
public Transform player;
public float sphereRadius;
void LateUpdate()
{
Vector3 pos = player.position;
float angle = Mathf.Atan2(pos.y, pos.x);
float distance = Mathf.Clamp(pos.magnitude, 0.0f, sphereRadius);
pos.x = Mathf.Cos(angle) * distance;
pos.y = Mathf.Sin(angle) * distance;
player.position = pos;
}
Just make sure using this won't counter effect your player movement script (that's why I put it in LateUpdate() in my example).

Related

Shoot from gun in top down shooter Unity3D

Currently I made bullet shoot from players position. Problem is that it shoots from player's center and not from the gun. I changed position of the bullet to make it shoot out from the gun. But the problem is that, when I start to rotate the player, bullet copies the rotation but not the position of the gun. It just stays on the same place. Here's my code:
public Transform firePoint;
public GameObject bulletPrefab;
public float bulletForce = 20f;
public void Shoot()
{
Vector3 newPosition = new Vector3(firePoint.position.x + 1, firePoint.position.y - 0.1f, firePoint.position.z);
GameObject bullet = Instantiate(bulletPrefab, newPosition, firePoint.rotation);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
rb.AddForce(firePoint.right * bulletForce, ForceMode2D.Impulse);
yield return new WaitForSeconds(0.5f);
}
Your issue is that you have hard-coded offset (x = 1, y = -0.1f) change. When you rotate your player 90 degrees, the offset for gun end becomes different.
There are two solutions for this:
Solution #1
Place your fire point Transform at the tip of the gun, make it child of the gun. That way the Transform will always follow the end of the gun.
Now, for instantiating, you can use firepoint.position without any modifications.
There are some drawbacks to this, mainly having strict objects hierarchy and it becomes harder to dynamically change guns as you will have to find and reassign fire point for each of them.
Solution #2
Have Vector3 firePointOffset;.
Once instantiating, calcualte the position of the fire point by doing
var firePointPosition = playerTransform.position + Vector3.Scale(playerTransform.forward, firePointOffset)`;
transform.forward returns Vector3 that points, well, forward for that specific transform. Vector3.Scale allows multiplying two vectors x * x, y * y, z * z;

Unity - Get new coordinates using old coordinates and line length between them

I am making a game where the player-object is running in a circle around origin. I want the player to be able to make the circle bigger or smaller. I have the distance between the new coordinates and origin and I have two old coordinates: current player coordinates and the origin. How do I get new coordinates aligned with the old coordinates and the origin using line lenght?
I am using unity and c#.
Can we see what you already have? This makes the process easier.
Maybe Transform.Rotate Could help you?
You only have to update the position of the player to "make the circle bigger". For example:
public class Example : MonoBehaviour
{
private Vector3 target = new Vector3(5.0f, 0.0f, 0.0f);
void Update()
{
// Spin the object around the world origin around the Yaxis 20 degrees/second.
transform.RotateAround(target, Vector3.up, 30 * Time.deltaTime);
}
Public void IncreaseDistance(float amount){
//you need a vector in de direction you want to move to. You get this by
// calculating the distance vector from the target to this.gameObject. Then normalize it
Vector3 direction = (transform.position - target).normalize; //to - from;
transform.position += direction * amount
}
}

How can I launch the ball based on the position of the touch on the screen?

So I am trying to make a game where you are rquired to set the angle and speed of a ball that has to bounce on specific platforms in order to get to the destination.
Now, how do I find the direction from where the finger touches, to the ball, in order to make it move "away from the finger".
I have tried to use the subtraction of vectors in order to get the direction but It does not work since the vectors are relative to the world origin...it always gives me a wrong direction...
How do I solve this problem, I need a direction vector relative to touch and player(the ball), not to world, so I can launch the ball.
You will see that in the next picture I am simulating a touch with the mouse arrow(let say the mouse arrow is the finger of the player.I want to launch the ball based on the distance and position of the finger relative to the ball. It works well in the code BUT ONLY if the ball is placed on the origin of the scene, so i think it's a mathematical problem with vectors that I don't know how to resolve...
Below is the code that I have by now. It is attached to the ball's gameobject:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
[SerializeField]
Camera playerCamera;
Rigidbody rb;
Vector3 touchPostion;
private void Awake()
{
rb = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
if (Input.GetMouseButton(0))
{
LounchPlayer();
}
}
void LounchPlayer()
{
Vector2 mousePos = Input.mousePosition;
touchPostion = (transform.position - playerCamera.ScreenToWorldPoint(
new Vector3(mousePos.x,
mousePos.y,
playerCamera.transform.position.z))).normalized;
rb.AddForce(touchPostion.normalized, ForceMode.Impulse);
}
}
When finding your touch position, the z component of ScreenToWorldPoint's parameter should be an appropriate distance along the camera's forward vector, definitely not the camera's world z position. playerCamera.nearClipPlane is appropriate here, but really any small constant (such as 0) would suffice.
Also, there is no need to normalize the launch direction twice.
Vector2 mousePos = Input.mousePosition;
touchPostion = (transform.position - playerCamera.ScreenToWorldPoint(
new Vector3(
mousePos.x,
mousePos.y,
playerCamera.nearClipPlane))
).normalized; // This isn't a position vector; it's a direction vector.
// The var name "touchPosition" is misleading and should be changed.
float launchMagnitude = 1f; // change this to adjust the power of the launch
rb.AddForce(touchPostion * launchMagnitude , ForceMode.Impulse);

How to move the camera on x- and z-axis so that viewpoint targets (0,0,0)?

I meanwhile found a solution, but I'd really like a code review. Perhaps there is an easier solution. I updated the script at the end of my question.
I have a camera in my scene with a specific position and rotation. I want to move the camera on the x- and z-axis so that it targets (0,0,0).
I have the position vector posVector of the camera object and the displacement vector dirVector, which is the viewing direction. Now at some point, posVector + dirVector will intersection the ground plane. This currently is (x,0,z) but I like to move the camera on the x- and z-axis so that this is (0,0,0). So I really need to know x and z.
I tried multiple things, but I still have trouble wrapping my head around vectors and intersections.
using UnityEngine;
[ExecuteInEditMode]
public class DebugHelper : MonoBehaviour {
public Camera mainCamera;
// This DebugHelper script runs in EditMode and will help me visualize vectors and also move the camera to where I want it to be.
private void Update()
{
Vector3 posVector = mainCamera.transform.position;
Vector3 dirVector = mainCamera.transform.rotation * Vector3.forward;
// Find scalar for dirVector that displaces posVector.y to 0
// posVector + dirVector * scalar = (x,0,z)
float scalar = Mathf.Abs(posVector.y / dirVector.y);
// Get the position vector of the current camera target at y=0.
Vector3 y0TargetVector = posVector + dirVector * scalar;
// Subtract the y0TargetVector from the posVector to move it back to zero. This works because y0TargetVector.y is 0 and therefore the height is the same.
mainCamera.transform.position -= y0TargetVector ;
Debug.DrawRay(posVector, dirVector * scalar, new Color(0, 1, 0));
}
}

something wrong with rotation controls in 2d top down shooter in unity3d

I am trying to get my character to face the mouse by rotating on its y axis. It rotates a little, but it do not face the mouse. The Camera's position is directly above the player, and its in orthographic view I see many other examples of top down shooters and there almost exactly like mine so i don't know whats the problem please help thank you.
using UnityEngine;
using System.Collections;
public class playermovementscript : MonoBehaviour {
public float movementspeed = 5f;
public float bulletspeed = 10f;
public GameObject bullet;
public GameObject shooter;
public Vector3 target;
public Camera camera;
// Use this for initialization
void Start () {
//refrence to main camera
Camera camera;
}
// Update is called once per frame
void Update () {
//call movement function in every frame
movement ();
// cheek for input of f in every frame if true execute shoot function
if (Input.GetKeyDown (KeyCode.F)) {
shoot();
}
}
void movement(){
// makes refrence to gameobjects rigidbody and makes its velocity varible to equal values of axis x and y
gameObject.GetComponent<Rigidbody>().velocity = new Vector3(Input.GetAxisRaw("Horizontal")*movementspeed,0,Input.GetAxisRaw("Vertical")*movementspeed);
// makes vector 3 type target equall to mouse position on pixial cordinates converted in to real world coordniates
target = camera.ViewportToWorldPoint (new Vector3(Input.mousePosition.x,Input.mousePosition.y,camera.transform.position.y - transform.position.y));
//target.x -= transform.position.x;
//target.z -= transform.position.z;
// states the vector 3 values of target
Debug.Log (target);
// makes object local z face target and iniziates up axis
transform.LookAt (target,Vector3.up);
}
Going to make an attempt to explain what's going on...
target = camera.ViewportToWorldPoint (new Vector3(Input.mousePosition.x,Input.mousePosition.y,camera.transform.position.y - transform.position.y));
The above code is trying to convert a mouse position which is in Screen Space (which measures the position from (0,0) to the width/height of the screen in pixels) to a Viewport Space (which measure the same screen but with a different measure, it measures the positions from (0,0) to (1,1)).
In Unity
Screen Space Measurement: Origin (0,0) to the max width/height
Viewport Measurement: Origin (0,0) to (1,1)
Reference: http://docs.unity3d.com/ScriptReference/Camera.html
If you desire to still use "ViewportToWorldPoint" then you could do a "ScreenToViewportPoint" then follow it with a "ViewPortToWorldPoint".
Otherwise, you could look into using "ScreenToWorldPoint" from the start.

Categories