How to add sprite to player material with script. I have a shop menu of player and when a like to select one sprite i like to add to player material but I don't know how to do this. I have my code but just this I don't know how to add. This is my code I made like this but don't work can someone tell me how to add playersprite to playermaterial.
public Material playerMaterial; // --> (player Material)
public Sprite[] playerSprite; // --> (Sprite i wish to add to the player)
GameManager.Instance.playerMaterial = GameManager.Instance.playerSprite[index];
private void SetSprite(int index)
{
activeSpriteIndex = index;
GameManager.Instance.state.activeSprite = index;
GameManager.Instance.playerMaterial = GameManager.Instance.playerSprite[index];
spriteBuySetText.text = "Current";
GameManager.Instance.Save();
}
A Unity3d material is more than just a texture so you need to set the texture of material via the SetTexture() method or mainTexture property. I'm assuming it's the Main Texture you want to change and not the bump or lighting maps.
public Material playerMaterial; // --> (player Material)
public Sprite[] playerSprite; // --> (Sprite i wish to add to the player)
private void SetSprite(int index)
{
activeSpriteIndex = index;
GameManager.Instance.state.activeSprite = index;
GameManager.Instance.playerMaterial.mainTexture = GameManager.Instance.playerSprite[index].texture;
spriteBuySetText.text = "Current";
GameManager.Instance.Save();
}
Related
I am new to C# and Unity.. I am trying to make a simple trading card game (tcg/ccg). For this first phase, I would like to make it to be played locally eg. own-self versus own-self. Would like to know how do we usually do for changing the perspective?
Eg: From the Player1's perspective as below image, once I ended my turn and pass it to player2, I would like to make it remain the same view but by showing player2's Hand card and Field card (also at the same time hide the Player1 hand card).
Below is just part of my code :
UiController.cs
[Header("General")]
[SerializeField] private GameObject BattleCardPrefab;
[Header("Player Detail")]
[SerializeField] private GameObject PlayerDeck;
[SerializeField] private GameObject PlayerHand;
[Header("Enemy Detail")]
[SerializeField] private GameObject EnemyDeck;
[SerializeField] private GameObject EnemyHand;
private void GetUserObject(int _player)
{
UserDeck = _player == 0 ? PlayerDeck.transform : EnemyDeck.transform;
UserHand = _player == 0 ? PlayerHand.transform : EnemyHand.transform;
}
public void InitDeck(int _player, List<Card> _deck)
{
foreach (var card in _deck)
{
GameObject resultCards = Instantiate(BattleCardPrefab, UserDeck);
resultCards.GetComponent<CardDetail>().card = card;
resultCards.GetComponent<CardDetail>().ShowCardBack(_player, resultCards, 0);
}
}
Player.cs
public Player(int _playerIndex, string _deckName)
{
playerIndex = _playerIndex;
deckName = _deckName;
}
public void GameStartSetUp(string _deckName){
//initDeck and extra
//blablabla
}
BattleManager.cs
Player player = new Player(0, "testdeck1");
Player enemy = new Player(1, "testdeck2");
void Start()
{
StartGame();
}
public void StartGame()
{
player.GameStartSetUp();
enemy.GameStartSetUp();
}
Please let me know if need more information from my side, mercy and thanks!
Scene Setup
Create 2 empty game objects, "Player 1 Main View" and "Player 2 Main View".
Use the following steps for both objects:
Parent your camera to the object and zero out the cameras position and rotation.
Move that object (with the camera as child) to where the camera should be.
Rotate the object so the camera view looks correct.
Unparent the camera.
Repeat for other views.
Code
From code we parent the camera to the appropriate view object and zero out the cameras local position and local rotation.
public Camera viewingCamera; // <- assign your camera in inspector
public Transform player1MainView; // <- assign "Player 1 Main View" object in inspector
public Transform player2MainView; // <- assign "Player 2 Main View" object in inspector
public void EnablePlayer1View()
{
EnableView(player1MainView);
// Hide player 2 canvas, flip over cards, etc.
// Show player 1 canvas, show cards, etc.
}
public void EnablePlayer2View()
{
EnableView(player2MainView);
// Hide player 1 canvas, flip over cards, etc.
// Show player 2 canvas, show cards, etc.
}
private void EnableView(Transform viewObject)
{
viewingCamera.transform.SetParent(viewObject);
viewingCamera.transform.localPosition = Vector3.zero;
viewingCamera.transform.localRotation = Quaternion.identity;
}
To switch the view to "Player 1", call EnablePlayer1View(). For "Player 2" call EnablePlayer2View().
so the player hits a button to create a box. I need this box to be randomly varying between a few colors. I also need this box to have a tag corresponding to said color. Green box - "greenBlock" tag etc.
I have instantiated the box and then try to change it's material with material.color. It doesn't do anything. I've seen suggestions of sharedMaterial but having tried that found it just ends up changing the color of every game object in the scene. I think I'm fetching the box prefabs renderer correctly? Any help would be appreciated!
Here's what I have so far:
public class ButtonScript : MonoBehaviour
{
public GameObject Box;
public Transform spawnpoint1;
public Transform spawnpoint2;
public Rigidbody2D player;
public Renderer boxRenderer;
[SerializeField]
private Color boxColor;
[SerializeField]
private AudioSource actionSound;
// Update is called once per frame
private void Start()
{
//boxRenderer = Box.gameObject.GetComponent<Renderer>();
boxRenderer = GameObject.Find("Box").GetComponent<Renderer>(); // Find the renderer of the box prefab
}
public void OnTriggerStay2D(Collider2D col)
{
if (player) // If it's the player in the collider trigger
{
if (Input.GetKeyDown(KeyCode.E))
{
Instantiate(Box, spawnpoint1.position, Quaternion.identity);
boxRenderer.material.color = boxColor; // change the color after it is instantiated
actionSound.Play();
}
}
}
}
boxRenderer.material.SetColor("_Color", boxColor);
or
boxRenderer.material.color = new Color(0.5, 0.5, 0.0, 1.0);
And when you instantiate the box, you need to get the render for the box at this point as it is a new object. So:
if (Input.GetKeyDown(KeyCode.E))
{
Box = Instantiate(Box, spawnpoint1.position, Quaternion.identity);
boxRenderer = Box.transform.GetComponent<Renderer>();
boxRenderer.material.color = boxColor; // change the color after it is instantiated
actionSound.Play();
}
Note you have creating a New color and assigning it, you can't modify the color there as it may be used on other objects that are using the same material.
Check out SetColor in the docs, that is setting the shader property called _Color which is the default color element in shaders, you can of course have more depending on the shader.
I'd like to get a single sprite which GameObject has in a SpriteRenderer component.
Unfortunately, this code returns the whole atlas, but I need to a part of this atlas.
Texture2D thumbnail = GetComponent<SpriteRenderer>().sprite.texture;
There is no native API to get single sprite from the SpriteRenderer and no API to access individual Sprite by name. You can vote for this feature here.
You can make your own API to get single sprite from Atlas located in the Resources folder like the image included in your question.
You can load all the sprites from the Atlas with Resources.LoadAll then store them in a dictionary.A simple function can then be used to access each sprite with the provided name.
A simple Atlas Loader script:
public class AtlasLoader
{
public Dictionary<string, Sprite> spriteDic = new Dictionary<string, Sprite>();
//Creates new Instance only, Manually call the loadSprite function later on
public AtlasLoader()
{
}
//Creates new Instance and Loads the provided sprites
public AtlasLoader(string spriteBaseName)
{
loadSprite(spriteBaseName);
}
//Loads the provided sprites
public void loadSprite(string spriteBaseName)
{
Sprite[] allSprites = Resources.LoadAll<Sprite>(spriteBaseName);
if (allSprites == null || allSprites.Length <= 0)
{
Debug.LogError("The Provided Base-Atlas Sprite `" + spriteBaseName + "` does not exist!");
return;
}
for (int i = 0; i < allSprites.Length; i++)
{
spriteDic.Add(allSprites[i].name, allSprites[i]);
}
}
//Get the provided atlas from the loaded sprites
public Sprite getAtlas(string atlasName)
{
Sprite tempSprite;
if (!spriteDic.TryGetValue(atlasName, out tempSprite))
{
Debug.LogError("The Provided atlas `" + atlasName + "` does not exist!");
return null;
}
return tempSprite;
}
//Returns number of sprites in the Atlas
public int atlasCount()
{
return spriteDic.Count;
}
}
Usage:
With the Example image above, "tile" is the base image and ball, bottom, people, and wallframe are the sprites in the atlas.
void Start()
{
AtlasLoader atlasLoader = new AtlasLoader("tiles");
Debug.Log("Atlas Count: " + atlasLoader.atlasCount());
Sprite ball = atlasLoader.getAtlas("ball");
Sprite bottom = atlasLoader.getAtlas("bottom");
Sprite people = atlasLoader.getAtlas("people");
Sprite wallframe = atlasLoader.getAtlas("wallframe");
}
You could put the image you need in the Resources folder by itself, then use the Resources.Load("spriteName") to get it. If you want to get it as a sprite, you would do the following:
Sprite thumbnail = Resources.Load("spriteName", typeof(Sprite)) as Sprite;
Source: https://forum.unity3d.com/threads/how-to-change-sprite-image-from-script.212307/
Well with the new Unity versions you can do it easily using SpriteAtlas class and GetSprite method:
https://docs.unity3d.com/ScriptReference/U2D.SpriteAtlas.html
So if you are working with the Resources folder you can do:
Resources.Load<SpriteAtlas>("AtlasName")
I am very new to Unity3d. I have a prefab which contains 6 quads making it a cube. I want to add image textures to different faces of cube.
I am getting images from a web service, so I have to add or change material in the script.
The problem I am facing is, I am not able to find material property in gameObject.
I have tried below code:
using UnityEngine;
using System.Collections;
public class shelfRuntime : MonoBehaviour {
public GameObject bottle;
public GameObject newBottle;
// Use this for initialization
void Start () {
iterateChildren(newBottle.transform.root);
GameObject rocketClone = (GameObject)Instantiate(bottle, bottle.transform.position, bottle.transform.rotation);
rocketClone.transform.localScale += new Vector3(1, 1, 1);
GameObject newBottleInMaking = (GameObject)Instantiate(newBottle, newBottle.transform.position, newBottle.transform.rotation);
Transform[] allChildren = newBottleInMaking.GetComponentsInChildren<Transform>();
foreach (Transform child in allChildren)
{
// do whatever with child transform here
}
}
void iterateChildren(Transform trans)
{
Debug.Log(trans.name);
if (trans.name == "Back") {
var ting = trans.gameObject.GetComponent<Renderer>();
// trans.renderer.material // there is no material property here
}
// Do whatever logic you want on child objects here
if (trans.childCount == 0) return;
foreach (Transform tran in trans)
{
iterateChildren(tran);
}
}
// Update is called once per frame
void Update () {
}
}
How to set material to quads? There are 6 quads inside my prefab.
You can no longer access some components directly in Unity. You must use GetComponent to get the component(Renderer) then access the material from it.
trans.renderer.material = ....
should be changed to
trans.GetComponent<Renderer>().material = yourNewMaterial;
Finally, when Cube or Quad is created in Unity, MeshRenderer is automtatically attached to them not Renderer. So, you might get run-time error with GetComponent<Renderer>(). Use MeshRenderer instead.
trans.GetComponent<MeshRenderer>().material = yourNewMaterial;
To create Material during run-time:
Material myNewMaterial = new Material(Shader.Find("Standard"));
The example below will create a Material, assign standard shader to it then change the texture to the texture from the myTexture variable before applying it to a GameObject.
public Texture myTexture;
void Start()
{
//Find the Standard Shader
Material myNewMaterial = new Material(Shader.Find("Standard"));
//Set Texture on the material
myNewMaterial.SetTexture("_MainTex", myTexture);
//Apply to GameObject
trans.GetComponent<MeshRenderer>().material = myNewMaterial;
}
I have a Class for create GameObjects and it get's sprite and .... to make a game object.
And I draw my Texture like this :
spriteBatch.Begin();
foreach (GameObject gameObject in Game.gameObjects)
{
if (gameObject.visible)
{
spriteBatch.Draw(gameObject.sprite.texture, gameObject.rect, gameObject.sprite.sourceRect, gameObject.color, MathHelper.ToRadians(gameObject.rotation), gameObject.sprite.origin, gameObject.spriteEffect, gameObject.layer);
}
}
foreach (Text text in Game.texts)
{
spriteBatch.DrawString(text.font, text.text, text.position, text.color, MathHelper.ToRadians(text.rotation), text.origin, text.scale, text.spriteEffects, text.layer);
}
spriteBatch.End();
I try some way to do this and crate new Object between game. for example I want to crate new bullet when i press space.
But I cant make new GameObject between Game;
Please help me.
Thanks.
Update :
I trying to add another game object while the game is running;
and the Game.gameObjects is a static list in Game1(I change Game1 name to Game)
and it's on GameObject class :
public GameObject(Sprite sprite)
{
this.sprite = sprite;
rectWidth = (int)sprite.texture.Width;
rectHeight = (int)sprite.texture.Height;
rect = new Rectangle((int)position.X, (int)position.Y, rectWidth, rectHeight);
Game.gameObjects.Add(this);
}
so I can get my GameObjects in game to render they or mange they;
then i have gameObjects is a list and it have All gameObjects in game
Your trying to add another game object while the game is running? Sorry your question is unclear.
I dont know if your Game.gameObjects is an array or list (Could you post the class, and where you initialize it?)
Game.gameObjects.Add(new GameObject(Sprite, position, whatever));
That possibly?