enter image description here I am instantiating prefabs and listing them on a scroll list. I am trying to teleport the player to instantiated prefab position when I click its reference on scroll list listing?
All suggestions are welcome.
From what I understand about your problem (explained in the comments rather than the question), you should be able to do this:
You can instantaneously move an object camera by setting its transform's position to the instantiated prefab's position when the click has occurred. For a camera, you probably have the camera view in X and Y dimension, so you want to move it to the new X and Y position but leave the Z-position as it is.
One potential solution: Add the following script to the GameObject with your Button component. Then add an event-listener on the Button component that points to the newly added script component and choose the MyTeleportingButton.OnClick as the target method. You also need to drag in the camera as a reference in the new script component.
public class MyTeleportingButton : MonoBehaviour
{
public GameObject camera;
public void OnClick()
{
// casting to Vector2 in order to move in 2D only
var currentPosition = camera.transform.position;
var newPosition = transform.position;
// set same depth as camera
newPosition.z = currentPosition.z;
camera.transform.position = newPosition;
}
}
Related
I created a pin object by script attached it to a sphere object .
using UnityEngine;
public class InstantiateMarkerPin : MonoBehaviour
{
public float Xpos;
public float Ypos;
public float Zpos;
public GameObject gameObjectPinInstantiate;
// Start is called before the first frame update
private void Start()
{
Xpos = 0.09f;
Ypos = 0.50f;
Zpos = 1.1f;
//The original object, where to instantiate, and the orientation of the new object
GameObject marker = (GameObject)Resources.Load("gameObjectPin");
Vector3 location = new Vector3(Xpos, Ypos, Zpos);
Quaternion rotation = Quaternion.Euler(0, 0, 0);
//The object the script is attached to
GameObject world = this.gameObject;
//Instantiate the prefab
gameObjectPinInstantiate = Instantiate(marker, location, rotation, world.transform);
Debug.Log("InstantiateMarkerPin class : Marker Location 2 :X, Y, Z : " + gameObjectPinInstantiate.transform.position);
}
// Update is called once per frame
private void Update()
{
}
}
This script is attached to the sphere Object .My sphere Object have shader material of earth image (globe).
This Instantiated Prefabs (gameObjectPin) on sphere surface appears on scene but not on game screen ,When I select the camera object in the camera preview also this object does not appear .
Scene view
Scene View when camera is selected
I am new to Unity what should I check or correct to appear my created object on the sphere
basically I am trying to add pins to corresponding country and label it .Similar to the globe on this http://kitsdmcc.com/news
Gameobject is created when Play is clicked on the sphere object
When the Pin Object is selected on play mode
Oh now I see it! What you did was only setting its GIZMO via this menu
which is only displayed in the SceneView.
This has nothing to do with the rendering in the GameView but is just a way for easier seeing and finding certain types of objects in the SceneView since usually they would be invisible if not selected.
From the Glossary:
A graphic overlay associated with a GameObject
in a Scene
, and displayed in the Scene View
. Built-in scene
tools such as the move tool are Gizmos
, and you can create custom Gizmos using textures or scripting. Some Gizmos are only drawn when the GameObject is selected, while other Gizmos are drawn by the Editor regardless of which GameObjects
are selected.
As noted in the comments there is no Component at all on your GameObject so nothing is rendered in the Gameview.
Of course now you could enable Gizmos also for the GameView via the Gizmos toggle
but I guess what you rather are trying to achieve is rather rendering that icon in the final App.
You probably would like to use e.g. the SpriteRenderer component here. And simply drag in your Icon to the Sprite property.
You might have to change the Pin Texture's TextureType to Sprite (2D and UI).
In general I would also recommend to Create a Prefab instead of using the Resources folder here.
There are also some changes I would do to your code in general:
public class InstantiateMarkerPin : MonoBehaviour
{
[Header("Settings")]
// directly use a Vector3 for setting the values
// | default value for this field
// | (only valid until changed via Inspector!)
// v
public Vector3 TargetPosition = new Vector3(0.09f, 0.5f, 1.1f);
// Instead of using Resources simply reference the
// created Prefab here
public GameObject gameObjectPinPrefab;
[Header("Outputs")]
public GameObject gameObjectPinInstantiate;
private void Start()
{
// Careful this currently ovewrites any value set via the
// Inspector. Later you will probably want to remove this.
TargetPosition = new Vector3(0.09f, 0.5f, 1.1f);
//As said I would rather use a prefab here and simply reference it above in the field
//gameObjectPinPrefab = (GameObject)Resources.Load("gameObjectPin");
//Instantiate the prefab
gameObjectPinInstantiate = Instantiate(gameObjectPinPrefab, TargetPosition, Quaternion.identity, transform);
Debug.Log("InstantiateMarkerPin class : Marker Location 2 :X, Y, Z : " + gameObjectPinInstantiate.transform.position);
}
// Always remove empty Unity methods
// They are called as messages if they exist
// and only cause unnecessary overhead
}
I have just started getting used to using Unity's new tilemap tool (UnityEngine.Tilemaps).
One issue I am having is that I don't know how to get the x,y coordinates of a placed tile via script. I am trying to move a scriptableObject on the tilemap in script to a new location that the player clicks, but I don't know how to get the coordinates of the clicked tile location. There doesn't seem to be any position property for the Tile class (the Tile knows nothing about its location), so the Tilemap must have the answer. I was not able to find anything in the Unity documentation for how to get the Vector3 coordinates for a selected tile in the Tilemap.
If you have access to the Tile instance you can use its transform (or the raycast hit from the click) to get its world position and than get the tile coordinates via the WorldToCell method of your Grid component (look at the documentation).
EDIT:
Unity seems to not instantiate the tiles but instead uses only one tile object to manage all tiles of that type, i wasn't aware of that.
To get the correct position you have to calculate it yourself. Here is an example of how to get the tile position at the mouse cursor if the grid is positioned at the xy-plane with z = 0
// get the grid by GetComponent or saving it as public field
Grid grid;
// save the camera as public field if you using not the main camera
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// get the collision point of the ray with the z = 0 plane
Vector3 worldPoint = ray.GetPoint(-ray.origin.z / ray.direction.z);
Vector3Int position = grid.WorldToCell(worldPoint);
I couldn't find a way to get the Grid's position from mouse click, so instead I used a Raycast to Vector3, and then converted that to coordinates via the WorldToCell method of the Grid component as per Shirotha's suggestion. This allows me to move the selected GameObject to a new position.
public class ClickableTile : MonoBehaviour
{
public NormalTile normalTile;
public Player selectedUnit;
private void OnMouseUp()
{
// left click - get info from selected tile
if (Input.GetMouseButtonUp(0))
{
// get mouse click's position in 2d plane
Vector3 pz = Camera.main.ScreenToWorldPoint(Input.mousePosition);
pz.z = 0;
// convert mouse click's position to Grid position
GridLayout gridLayout = transform.parent.GetComponentInParent<GridLayout>();
Vector3Int cellPosition = gridLayout.WorldToCell(pz);
// set selectedUnit to clicked location on grid
selectedUnit.setLocation(cellPosition);
Debug.Log(cellPosition);
}
}
}
On an aside, I know how to get the Grid location, but now how to query it. I need to get the GridSelection static object from Grid, and then get its position.
I'm trying to learn Unity by myself. I'm recreating pong in 3d with Unity objects. I started a few minutes ago and every time I throw any input into the pad its y coordinate shifts to 2.6, I have no idea why. Can someone help?
public class PadMovement : MonoBehaviour {
private CharacterController pad;
private Vector3 direction;
private Vector3 movement;
[SerializeField] private float speed = 50.0f;
// Use this for initialization
void Start() {
pad = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update() {
direction = new Vector3(Input.GetAxis("Horizontal"), 0, 0);
movement = direction * speed;
pad.Move(movement * Time.deltaTime);
}
}
SOLVED: there was a capsule collider out of place!
Afternoon, I recently copied your code into a 'Unity3d', ".cs", File and actually I created a cube and placed my game into a 2d mode, After this I named my file "PadMovement", after that I dragged it onto my newly created cube, Once I had done that I tried to click play and noticed that my cube didn't have a "CharacterController", attached to my cube, Once I had done that and clicked play I was eligible to have my "paddle", smoothly move around the screen # 50.0f along the X axis.
Knowingly, My Input came from the "Character Controller", My Speed came from the Serial field you had for speed!
Do you by any chance have a CapsuleCollider Component or some other collider on the same GameObject that you have this PadMovement Component on? That sounds like a height where it might just be trying to pop the object out of ground collision.
It should be harmless if that's all it is. If you really want an object to be at y of 0 you can attach it to a parent object and have that parent stay at 0.
I have made a gameobject together with some children gameobject to represent the information to show up when specific circumstances occurred.
I have already ajusted the position of the information gameobject(together with its' children) in the cameraarea. The thing is that I want to move the gameobject(together with its' children) out of the camera, maybe on top or maybe on left. Following is the scratch to demonstrate the position I want to put it:
So that I could move the information gameobject and its' children (Red box) with some movement effect when needed, I have no problem with moving it back but could find an elegant way to move it out of the camera when the game started.
Mostly because I don't know how to calculate the position out of the camera.
Maybe find the upper border of the camera and the size of the gameobject and its children?
I know I could do this by maybe add a marker gameobject to represent the downer border of the information gameobject, and move it until it's not visible, but is there a more elegant way?
Any ideas?
For this one, I would use the following trick: use any method (animation, coroutine, Update method...) to move your item out of screen the way you desire. Then you can use the OnBecameInvisible event which is called when the item does not need to be rendered on any camera anymore. The event will there be used to detect that the parent object moved out of screen, and that you want to stop the current movement. You then just need to define in this event that you want to stop the current moving behavior, and you will be done.
void OnBecameInvisible() {
// Stop moving coroutine, moving in Update or current animation.
}
There are probably more elegant ways of doing it as you said, but I think this method should be enough for what you want to achieve.
It took me time, but I found this way for you, attach this script to your gameObject:
public Renderer rend;
//drag the camera to the script in the inspector
public Camera camera1;
Vector3 bottomleft;
Vector3 topright;
void Start()
{
rend = GetComponent<Renderer>();
//the top-right point of the camera bounds
topright= camera1.ViewportToWorldPoint(new Vector3(0, 0, transform.position.z));
//the bottom-left point of the camera bounds
bottomleft = camera1.ViewportToWorldPoint(new Vector3(1, 1, transform.position.z));
StartCoroutine(MoveUp());
}
IEnumerator MoveUp()
{
//while the position and the height are lower that the Y of top right
while (transform.position.y + rend.bounds.size.y < topright.y)
{
//move the object to the new position (move it up)
transform.position = new Vector3(transform.position.x, transform.position.y + .01f, transform.position.z);
//and wait for 1/100 of a second
yield return new WaitForSecondsRealtime(.001f);
}
}
you can play with the WaitForSecondsRealtime value to change the velocity of moving.
I have 2 Spheres in my scene. I want to be able to drag and drop my mouse from one sphere to the other, and have an indicator (a straight line for example) while dragging. After releasing the mouse button, I want to store in the first sphere the other sphere (as GameObject).
I need this in UnityScript, but I can accept C# ideas.
So far I have thought about onMouseDown event on the first Sphere, and then onMouseEnter to the other sphere, I'll store the data in some global variable (which I donno how to do yet) and in case of onMouseExit I'll just put the global variable as null.
Then onMouseUp on the first Sphere I'll store the global variable in the pressed object (the sphere).
Any tips and tricks on how to do it?
Assumptions/Setup
You're working in a 2D worldspace; the logic for dragging the object for this part of the solution would need changing.
Setting parent after click drag, referred to setting the object you didn't click to be the child of the parent you did click on.
The camera should be an orthographic camera; using a perspective camera will cause the dragging to not align with where you think it should be.
In order to make the dragging work, I created a quad that was used as the 'background' to the 2D scene, and put that on a new layer called 'background'. Then setup the layermask field to only use the background layer.
Create and setup a material for the line renderer, (I'm using a Particles/Additive shader for the above example), and for the parameters of the line renderer I'm using Start Width: 0.75, End Width: 0, and make sure Use World Space is ticked.
Explanation
Firstly setup the otherSphere field to be pointing to the other sphere in the scene. OnMouseDown and OnMouseUp toggle the mouseDown bool, that is used to determine if the line renderer should be updated. These are also used to turn on/off the line renderer, and set/remove the parent transform of the two spheres.
To get the position to be dragged to, I'm getting a ray based off of the mouse position on screen, using the method ScreenPointToRay. If you wanted to create add smoothing to this drag functionality, you should enable the if (...) else statement at the bottom, and set the lerpTime to a value (0.25 worked well for me).
Note; when you release the mouse, the parent is immediately set, as such both objects end up getting dragged, but the child will return to it's former position anyway.
[RequireComponent(typeof(LineRenderer))]
public class ConnectedSphere : MonoBehaviour
{
[SerializeField]
private Transform m_otherSphere;
[SerializeField]
private float m_lerpTime;
[SerializeField]
private LayerMask m_layerMask;
private LineRenderer m_lineRenderer;
private bool m_mouseDown;
private Vector3 m_position;
private RaycastHit m_hit;
public void Start()
{
m_lineRenderer = GetComponent<LineRenderer>();
m_lineRenderer.enabled = false;
m_position = transform.position;
}
public void OnMouseDown()
{
//Un-parent objects
transform.parent = null;
m_otherSphere.parent = null;
m_mouseDown = true;
m_lineRenderer.enabled = true;
}
public void OnMouseUp()
{
//Parent other object
m_otherSphere.parent = transform;
m_mouseDown = false;
m_lineRenderer.enabled = false;
}
public void Update()
{
//Update line renderer and target position whilst mouse down
if (m_mouseDown)
{
//Set line renderer
m_lineRenderer.SetPosition(0, transform.position);
m_lineRenderer.SetPosition(1, m_otherSphere.position);
//Get mouse world position
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out m_hit, m_layerMask))
{
m_position.x = m_hit.point.x;
m_position.y = m_hit.point.y;
}
}
//Set position (2D world space)
//if (m_lerpTime == 0f)
transform.position = m_position;
//else
//transform.position = Vector3.Lerp(transform.position, m_position, Time.deltaTime / m_lerpTime);
}
}
Hope this helped someone.