So I'm dynamically adding images to a scrollview from a json file/ url
I like to make the images clickable gameobject, but have no idea how to do this in c# ( void OnMouseDown() ???)
IEnumerator AddFeedItem (int index)
{
WWW www = new WWW (ModelURL); // img url
yield return www;
GameObject newsimageObject = tempFeedItem.transform.FindChild ("newsimage").gameObject;
Image newsImage = newsimageObject.GetComponent<Image> ();
Texture2D tempTex = photos [index % 10];
SpriteRenderer renderer = newsImage.GetComponent<SpriteRenderer>();
Sprite sprite = new Sprite();
sprite = Sprite.Create(www.texture, new Rect(0, 0, 455, 230),new Vector2(0, 0),100.0f);
newsImage.sprite = sprite;
}
This is an Image/Canvas. You should avoid Raycast and OnMouseDown. To detect touch with Image/Canvas, you use have to derive from IPointerDownHandler or IPointerClickHandler then implement the functions from them. OnMouseDown or Raycast should be used only if the Object is a 3D model or if the Object is a Sprite that is NOT under a Canvas. In that case, a collider is required. In this case, you are using the Image component, so I assume this is under Canvas.
public class YourClass : MonoBehaviour,IPointerDownHandler,IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("Clicked");
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Down");
}
}
Try to create a BoxCollider2D object atached to that GameObject and then Use
Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Mouse.position), Vector2.zero);
to test if there are any Collider in the Mouse.position.
Related
I have a 3d game and when my player is activating a button, it spawn a clone of an object (using instantiate). I dont want my player to be able to have more than 1 box(clone) at a time. Therefore, If the player click the button to spawn a clone, and there is already a clone present, I want to destroy the already present clone. I will put the code I use to spawn the clone down bellow.
(Note that "transform.position" in both void OnMouseDown and OnMouseUp is used to change the apparence of the button when pressed)
public class Button : MonoBehaviour {
public Rigidbody box;
void OnMouseDown()
{
transform.position = new Vector3(-3.5f, 1.45f, 7.0f);
Rigidbody clone;
clone = Instantiate(box, new Vector3(0f, 10f, 11f), transform.rotation);
}
void OnMouseUp()
{
transform.position = new Vector3(-3.5f, 1.5f, 7.0f);
}
}
You need to store your "clone" in a class reference like you do for your original box, and check if it's not empty. If its present then destory.
public class Button : MonoBehaviour {
public Rigidbody box;
public Rigidbody clone;
void OnMouseDown()
{
transform.position = new Vector3(-3.5f, 1.45f, 7.0f);
if(clone != null)
{
Destroy(clone);
}
clone = Instantiate(box, new Vector3(0f, 10f, 11f), transform.rotation);
}
void OnMouseUp()
{
transform.position = new Vector3(-3.5f, 1.5f, 7.0f);
}
}
I am beginner of game development I want to make when Player is enter the trigger the game is over so player's movement and camera rotation is stop. This is my code I can make player's movement is stop but camera rotate is not stop I can still rotate so help me!
public GameObject canvas;
public Transform Camera;
void Start()
{
canvas.gameObject.SetActive(false);
}
void OnTriggerEnter(Collider col)
{
canvas.gameObject.SetActive(true);
Time.timeScale = 0;
Camera.transform.rotation = Quaternion.Euler(0, 0, 0);
}
One easy way would be to add a bool variable in your Camera script and change it when the player enters and exit the trigger like so :
public bool isLocked;
void DoRotate() {
if(!islocked)
// do stuff
}
Another possibility would be to manually overwrite the camera rotation as long as the player is in the trigger zone which is not the ideal solution. In this case, you need to use the function OnTriggerStay instead of OnTriggerEnter.
For example :
public GameObject canvas;
public Transform Camera;
void Start()
{
canvas.gameObject.SetActive(false);
}
void OnTriggerEnter(Collider col)
{
canvas.gameObject.SetActive(true);
Time.timeScale = 0;
}
void OnTriggerStay(Collider col)
{
Camera.transform.rotation = Quaternion.Euler(0, 0, 0);
}
Im working on a first person shooter. I have an aim function, which puts the pistol right in front of the camera, to make it look like your holding it in front of you. Im trying to make it so the pistol will also rotate with the camera on the Z axis, so that way the pistol wont stay still, because that looks odd and gets in the way. To do this, I tried this:
GPR.gun.transform.rotation = Quaternion.Euler(0, 0, plrCam.transform.rotation.z);, however this ends up rotating the gun very slightly around the z axis, and mainly rotating it around the y axis whenever I move my camera. I am a beginner programmer in Unity so please try to make answers more digestible to beginners so I can understand it. Here is my full script:
using System.Collections.Generic;
using UnityEngine;
public class PistolFire : MonoBehaviour
{
//Gun Properties
public float range = 50f;
public float damage = 10f;
//Sensitivity decrease for looking down the sights
public float downSights = 5f;
//Other vars
private playerGunControls playerGun;
private GameObject plrCam;
private Camera fpsCam;
private ParticleSystem muzzleFlash;
private GameObject impactEffect;
private bool aimed = false;
private GameObject aimPos;
private GunPickupRaycast GPR;
private GameObject handPos;
private GameObject Player;
// Start is called before the first frame update
void Start()
{
//Getting objects because gun is instantiated, so this is necessary
plrCam = GameObject.Find("Player Camera");
playerGun = plrCam.GetComponent<playerGunControls>();
fpsCam = plrCam.GetComponent<Camera>();
muzzleFlash = GetComponentInChildren<ParticleSystem>();
impactEffect = GameObject.Find("Impact Effect");
aimPos = GameObject.Find("aimPos");
GPR = plrCam.GetComponent<GunPickupRaycast>();
handPos = GameObject.Find("Hand Pos");
Player = GameObject.Find("Player");
}
// Update is called once per frame
void Update()
{
//Check for shoot button down
if (Input.GetButtonDown("Fire1"))
{
if (playerGun.holding == "Pistol")
{
Shoot();
}
}
//Check if aim button down
if (Input.GetButton("Fire2"))
{
if (playerGun.holding == "Pistol")
{
Aim();
}
}
//Check if no longer aiming to reset to normal
if (aimed == true && !(Input.GetButton("Fire2")))
{
Unaim();
}
}
void Shoot()
{
muzzleFlash.Play();
RaycastHit hit;
if(Physics.Raycast(plrCam.transform.position, plrCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Health health = hit.transform.GetComponent<Health>();
if (health != null)
{
health.TakeDamage(damage);
}
//Instantiate the Impact Effect
GameObject IE = Instantiate(impactEffect, hit.point, Quaternion.identity);
Destroy(IE, 1.5f);
}
}
void Aim()
{
aimed = true;
Debug.Log("Aiming");
GPR.gun.transform.position = aimPos.transform.position;
GPR.gun.transform.rotation = Quaternion.Euler(0, 0, plrCam.transform.rotation.z);
}
void Unaim()
{
GPR.gun.transform.position = handPos.transform.position;
Debug.Log("No longer aiming");
aimed = false;
}
}
I fixed my problem by making the gun a child of my camera instead of a child of my player.
I want to instantiate a projectile and be able to rotate it as a child of a parent player object.
My player has a 2DRigidbody and box collider 2D, my projectiles also have a 2DRigidbody and box collider 2D, so when I shoot them from the player they bounce the player everywhere, but when I try to instantiate them elsewhere the player either jumps to that location or they appear away from the player, so I'd like to instantiate them as a child of the player.
My code for the Player
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
// Calls Variables
public Rigidbody2D lazer;
public float speed = 1.0f;
public float hitpoints = 100;
public float lazerlevel = 1;
Transform ParentPlayer;
// Initalizes variables
void Start () {
}
// Updates once per frame
void Update () {
var move = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
transform.position += move * speed * Time.deltaTime;
if (Input.GetButtonUp("Fire1")) {
//Rigidbody2D instance = Instantiate(lazer, transform.position = new Vector3(0,-5,0), transform.rotation) as Rigidbody2D;
//Vector3 fwd = transform.TransformDirection(Vector3.down);
//instance.AddForce(fwd * 20 * lazerlevel);
GameObject objnewObject = (GameObject)Instantiate(lazer, new Vector3(0, 0, 0), transform.rotation);
objnewObject.transform.parent = ParentPlayer;
}
}
}
And my code for the lazer
using UnityEngine;
using System.Collections;
public class PlayerProjectileDoom : MonoBehaviour {
void ontriggerenter() {
Destroy(gameObject);
}
void Update () {
Destroy(gameObject, 2F);
}
}
You never assigned ParentPlayer in Player script. And you want to assign instantiated object as the child of Player. So the possible way to achieve this is to instantiate your object first, set it as child and then set the transformations to identity because after setting it as child its transformations will become relative to parent.
For example,
void Update () {
var move = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0);
transform.position += move * speed * Time.deltaTime;
if (Input.GetButtonUp("Fire1")) {
GameObject objnewObject = Instantiate(lazer) as GameObject;
objnewObject.transform.parent = transform;
objnewObject.transform.localRotation = Quaternion.identity;
objnewObject.transform.localPosition = Vector3.zero;
}
}
Second thing is in your PlayerProjectileDoom script. You did implement OnTriggerEnter in wrong way. You should be careful when you are implementing these messages.
Third thing is you are calling Destroy in Update method, however it will work if you put it in Start. I'd recommend use Update at least as possible and absolutely not for these kind of events.
It should be like,
using UnityEngine;
using System.Collections;
public class PlayerProjectileDoom : MonoBehaviour {
void Start(){
Destroy(gameObject, 2F);
}
// For 3D colliders
void OnTriggerEnter(Collider coll) {
Destroy(gameObject);
}
// For 2D colliders
void OnTriggerEnter2D(Collider2D coll) {
Destroy(gameObject);
}
void Update () {
}
}
So you are using 2D colliders so you should go with 2D collider message and remove the 3D one.
An extra note: OnTriggerEnter or OnTriggerEnter2D will execute only iff you set colliders as Trigger. You can see this Trigger check in Inspector by selecting that gameobject having any collider. But if it is not set to Trigger then you should use OnCollisionEnter2D(Collision2D coll)
Inside the script code I want add the possibility to change its sprite. So the player mouseover the sprite,it changes into the other sprite already added to the project. Can you provide me a sample code to do this?
var newSprite : Sprite;
function Start () {
print(gameObject.name);
}
void OnMouseEnter()
{
print("hii detected");
//targetGui.texture = hoverTex;
GetComponent(SpriteRenderer).sprite = newSprite;
}
void OnMouseExit()
{
}
You can make both of the sprite as gameObjects. Then disable the Sprite Renderer of the newSprite object and attach the script to the current Sprite (first sprite).
public GameObject newSprite;
private Vector3 currentSpritePosition;
void OnMouseEnter(){
//getting the current position of the current sprite if ever it can move;
currentSpritePosition = transform.position;
//then make it invisible
renderer.enabled = false;
//give the new sprite the position of the latter
newSprite.transform.position = currentSpritePosition;
//then make it visible
newSprite.renderer.enabled = true;
}
void OnMouseExit(){
//just the reverse process
renderer.enabled = true;
newSprite.renderer.enabled = false;
}
You can also diable at start as follows:
void Start(){
newSprite.renderer.enabled = false;
}
EDIT: You should add a collider to the current sprite for the OnMouseOver and OnMouseExit to work.