I build my first game and want to Instantiate an object,
the player should be allowed to choose where to instantiate it. It should be on the ground(plane) and the object(cube) should follow the mousePos. That's where the problem occurs. I tried for hours now (at least 5) but can't figure it out. I tried raycast and screentoWorld stuff, but the object doesn't follow my mouse perfectly. The best i could get is, if i moved right, the cube moved right, same for all the other directions but it did not move the same speed as my mouse, so it was not at the same pos and i can't "OnMouseDown" it(except for the very middle of the screen) I use an Orthographic Camera, the speed the Cube is moving with the mouse seems to be dependent on my camera Size, but I want it to work in any size etc. Thanks for any help in advance.
This is my code:
using UnityEngine;
using System;
public class VorKasernenBau : MonoBehaviour
{
public static event Action<Vector3> onBuildBuilding;
public Camera cam;
public GameObject kasernePrefab;
private void Update()
{
moveMe();
}
private void OnMouseDown()
{
if (true/*if genug platz*/)
{
Instantiate(kasernePrefab, transform.position, Quaternion.identity, transform.parent);
if (onBuildBuilding != null)
onBuildBuilding.Invoke(transform.position);
Destroy(gameObject);
}
}
private void moveMe()
{
Ray ray = cam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.CompareTag("Ground"))
{
transform.position = hit.point + Vector3.up;
Debug.Log("test");
}
}
}
}
Update1:
The z Position seems to be okay, but the xPos isn't following perfectly.
I moved the object with another function. (cam.screentoworld and y value to 1) This problem is solved(even known i am not really happy with this solution), but another problem comes with it. if i move the screen in play mode (through drag and drop), the mousePos is not calculated right since the calculated mousepos isn't translated like the screen. Anyways have a great night and thanks for the help.
Vector3 pos = cam.ScreenToWorldPoint(Input.mousePosition);
transform.position = new Vector3(pos.x,1,pos.z);
Related
Like the image above, I want to place an object so that it faces away from the surface( I am using graphics instancing to create grass). I assume this will have to do something with the surface normals/ raycasting, but I can not figure out how to do it. I'm using unity and c# so answers relating to that would be great.
I haven't really been able to get off my feet with this problem, but I've tried rotating it so that it faces up always, but that results in a lot of clipping and weird behavior.
Complicated problem of which Unity already has a solution. Here is a script to automatically align it to the normal. I've also added a LayerMask option so you only hit the correct layer on your check as well as a max height value. Remember to set both from the Inspector.
public class NormalRotation : MonoBehaviour
{
public float maxHeight = 2f;
public LayerMask layer;
void Update() => RotateTransformToNormal();
void RotateTransformToNormal() =>
transform.rotation = Quaternion.FromToRotation(transform.up, GetNormal()) * transform.rotation;
Vector3 GetNormal()
{
// Raycast down from the transform
Ray ray = new Ray(transform.position, Vector3.down);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, maxHeight, layer))
{
return hit.normal;
}
return transform.up;
}
}
So my game is sort of like a 3d top down shooter, so I want my gun to shoot wherever the mouse is and it wont go to the mouse unless im shooting down. If you've seen brackyes game called ball wars, im sort of trying to replicate one like that but the projectile is not shooting the right way.
I got my script from blackthornprods ranged combat tutorial (which is for 2d so maybe thats the issue but I dont know how to solve it) :
public float speed;
public float lifeTime;
private void Start()
{
Invoke("DestoryProjectile", lifeTime);
}
private void Update()
{
transform.Translate(transform.up * speed * Time.deltaTime);
}
void DestroyProjectile()
{
Destroy(gameObject);
}
Appreciate anyone to try!
Here is my other script:
Camera mainCam;
public GameObject projectile;
public Transform shotPoint;
private float timeBtwShots;
public float startTimeBtwShots;
void Awake()
{
mainCam = Camera.main;
}
void Update()
{
float objectDepthFromCamera = Vector3.Dot(
transform.position - mainCam.transform.position,
mainCam.transform.forward);
Vector3 cursorWorldPosition = mainCam.ScreenToWorldPoint(Input.mousePosition
+ Vector3.forward * objectDepthFromCamera);
Vector3 localUpNeeded = Vector3.Cross(Vector3.forward,
cursorWorldPosition - transform.position);
transform.rotation = Quaternion.LookRotation(Vector3.forward, localUpNeeded);
if(timeBtwShots <= 0)
{
if (Input.GetMouseButtonDown(0))
{
Instantiate(projectile, shotPoint.position, transform.rotation);
timeBtwShots = startTimeBtwShots;
}
}
else
{
timeBtwShots -= Time.deltaTime;
}
}
Projectile not shooting direction of my weapon. Simple solution -
First instantiate or pool the instance of projectile.
Set rotation of projection from the rotation of weapon & set location to spawn point
Now fire, or whatever strategy you are using
Consider Global rotation, if you need help, tell me, I will edit and give a snippet of code.
This should work. If doesn't post all necessary code, I will give a better solution.
Here is sample github project I created, just for you. I opened Unity nearly after a year. Please check all the versions.
Must check :
firing in facing direction 💋
just instantiate at spawn point
just added some rotation
I think this should give you concept.
Press X for a rantom rotation
Press Space to shoot a projectile :lol:
The white cube shows that it always shoots at a constant direction
I'm having trouble finding my mistake regarding my automatic movement script. I will explain first what i tried to do so you can understand it better. So i am programming in c# in unity. It is for VR. I created a button, that works as a trigger when you are looking at it. When looking at the button a door goes down and the player should move inside a castle (automatically).
The door script works fine but the player is not moving at all. I used a public Vector3 where I declared the position inside the castle where the player should move to (it is only a forward direction).
Unfortunately the code looks fine to me and i cant figure it out why my player wont move :/.
So I tried playing around with the Vectors but i had no luck.
{
public float speed = 0.5f;
public Vector3 castlePosition;
private Vector3 targetPosition;
// Start is called before the first frame update
void Start()
{
targetPosition = transform.position;
}
// Update is called once per frame
void Update()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit))
{
if(hit.transform.GetComponent<DoorButton>() != null)
{
hit.transform.GetComponent<DoorButton>().OnLook();
MoveToCastle ();
}
}
transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * speed);
}
private void MoveToCastle()
{
targetPosition = castlePosition;
}
}
I was expecting that the MoveToCastle function would put my player inside the castle (at the position that I declared earlier).
Once again the OnLook function from my door is working.
Thank you in advance for your help. :)
Your MoveToCastle stops working as soon as raycast becomes false. You probably should set off some continuous process of moving to target when the raycast hits. For example start coroutine something like this:
IEnumerable MoveToCastle()
{
targetPosition = castlePosition;
while (transform.position != castlePosition) // careful here! see below
{
transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * speed);
yield return null;
}
}
Better to compare target and transform coordinates by subtracting and comparing to some small value, otherwise it can go there quite long.
I'm trying to have various interactions take place when looking at a game object, but it doesn't seem to work when I'm too close. I'm using Unity's first person controller and the script it attached to the camera.
void Update () {
RaycastHit hit;
Vector3 forward = transform.TransformDirection(Vector3.forward) * 10;
if(Physics.Raycast(transform.position,(forward), out hit) ){
GameObject lookingAt = hit.collider.gameObject;
if (lookingAt.layer == 9)
{
Debug.Log("This doesn't always show up.");
}
}
}
I put
public LayerMask interactionLayers = ~0;
And selected the elements that should be detected in the inspector. That seemed to fix the issue.
Thanks.
Okay so I've been fighting with this script for a couple days now. I've made progress in other aspects but I can't seem to get my enemies to properly chase the player character.
The script is supposed to have the enemies wander until an empty child 'eyes' sees the player. Then it should start chasing the player. Think pac-man. What it's doing right now is making one loop of it's wander cycle and then stopping and not seeing the player at all.
This is the code that I've got so far for that script -
using UnityEngine;
using System.Collections;
public class dudeFollow : MonoBehaviour {
Transform tr_Player;
float f_MoveSpeed = 3.0f;
private DudeMove moveScript;
public Transform eyes;
public float sightRange = 3f;
// Use this for initialization
void Start () {
tr_Player = GameObject.FindGameObjectWithTag("Player").transform;
moveScript = GetComponent<DudeMove>();
}
// Update is called once per frame
void Update () {
RaycastHit hit;
if (Physics.Raycast (eyes.transform.position,eyes.transform.forward, out hit,sightRange) && hit.collider.CompareTag ("Player")) {
transform.position += transform.forward * f_MoveSpeed * Time.deltaTime;
moveScript.enabled = false;
}
}
}
Any help or tips would be appreciated.
Because you have 2D game, what most likely happens is your enemy wonders away on z-axis as well, but because it's 2D, you can't see it. So switch to 3D mode in your main scene window and see if that's the case.
If it is, just reset z-axis to 0 on every frame and disable angular momentum :) I had this happen with 2D games.
void Update () {
RaycastHit hit;
if (Physics.Raycast (eyes.transform.position,eyes.transform.forward, out hit,sightRange) && hit.collider.CompareTag ("Player")) {
transform.position += transform.forward * f_MoveSpeed * Time.deltaTime;
moveScript.enabled = false;
}
transform.position.z = 0; // or something along those lines, I don't remember the syntax exactly.
}