I found a code on the Internet that works like Python's random.choices():
static class RandomUtils
{
public static string Choice(this Random rnd, IEnumerable<string> choices, IEnumerable<int> weights)
{
var cumulativeWeight = new List<int>();
int last = 0;
foreach (var cur in weights)
{
last += cur;
cumulativeWeight.Add(last);
}
int choice = rnd.Next(last);
int i = 0;
foreach (var cur in choices)
{
if (choice < cumulativeWeight[i])
{
return cur;
}
i++;
}
return null;
}
}
Added to my code:
using UnityEngine;
using System.Linq;
using System.Collections.Generic;
public class GroundTile : MonoBehaviour
{
GroundSpawner groundSpawner;
public GameObject player;
private bool doDoubleSpawn;
private int chanceForDoubleSpawn = 45;
void Start()
{
groundSpawner = GameObject.FindObjectOfType<GroundSpawner>();
player = GameObject.Find("Tractor");
SpawnObstacle();
chanceForDoubleSpawn = GroundSpawner.levelObstaclesMultiplier;
}
// Spawn weight values for obstacles
private int boxWeightValue = 40;
private int antitankWeightValue = 40;
private int barricadeWeightValue = 40;
private int wheelsWeightValue = 40;
private int molotovItemWeightValue = 5;
// Prefabs
public GameObject obstaclePrefab;
public GameObject boxPrefab;
public GameObject antitankPrefab;
public GameObject barricadePrefab;
public GameObject wheelsPrefab;
public GameObject tankLevel1Prefab;
public GameObject molotovItemPrefab;
// Destroy if player too far away
void Update()
{
if(transform.position.z < player.transform.position.z - 30)
{
Destroy(gameObject);
}
}
}
static class RandomUtils
{
public static string Choice(this Random rnd, IEnumerable<string> choices, IEnumerable<int> weights)
{
var cumulativeWeight = new List<int>();
int last = 0;
foreach (var cur in weights)
{
last += cur;
cumulativeWeight.Add(last);
}
int choice = rnd.Next(last);
int i = 0;
foreach (var cur in choices)
{
if (choice < cumulativeWeight[i])
{
return cur;
}
i++;
}
return null;
}
}
But it gives me an error:
Assets\Scripts\GroundGenerator\GroundTile.cs(61,30): error CS0721: 'Random': static types cannot be used as parameters
How do I fix this? Maybe there is another way to write this function?
UPD: code that instantiate GroundTile:
using UnityEngine;
public class GroundSpawner : MonoBehaviour
{
public GameObject groundTile;
public GameObject groundTileEnd;
public GameObject player;
Vector3 nextSpawnPoint;
private int numOfTiles = 10;
private int plusTiles = 5;
private int count = 0;
public static int level = 1;
public static int levelObstaclesMultiplier = 45;
// Weight values for tanks and items
public static int tankWeightValue = 100;
public static int molotovItemWeightValue = 10;
public static int molotovItemWeightValuePlus = 3;
public void SpawnTile()
{
GameObject temp = Instantiate(groundTile, nextSpawnPoint, Quaternion.identity);
nextSpawnPoint = temp.transform.GetChild(1).transform.position;
}
public void SpawnEndTile()
{
GameObject temp = Instantiate(groundTileEnd, nextSpawnPoint, Quaternion.identity);
nextSpawnPoint = temp.transform.GetChild(1).transform.position;
}
void Start()
{
for (int i = 0; i < 10; i++)
{
SpawnTile();
}
SpawnEndTile();
InvokeRepeating("Spawn", 1.5f, 1.5f);
}
public void Spawn()
{
if (Time.timeScale != 0 && PlayerController.forwardSpeed != 0)
{
if (count != numOfTiles)
{
SpawnTile();
count += 1;
}
else
{
SpawnEndTile();
numOfTiles += plusTiles;
count = 0;
if (levelObstaclesMultiplier <= 65)
{
levelObstaclesMultiplier += 1;
}
}
}
}
}
This code seems to have been written for C#'s System.Random rather than the Unity-specific UnityEngine.Random class. You can resolve the error by specifying System.Random in the parameters:
public static string Choice(this System.Random rnd, IEnumerable<string> choices, IEnumerable<int> weights)
On the parameters, just replace "Random" with "System.Random", the error is because it thinks you're using UnityEngine.Random, which is a static type.
public static string Choice(this System.Random rnd, IEnumerable<string> choices, IEnumerable<int> weights)
so I am coming to the end of a project I am currently working on and am running into a major issue with the audio. For some reason, my three recently added audio clips are playing at the start of my game instead of only playing on collision. I do only have one audio source on my player with the play on awake not checked. Could anyone explain what I am doing wrong?
The added clips are public AudioClip splashSound; public AudioClip reloadSound;and public AudioClip pageSound;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.SceneManagement;
public class RubyController : MonoBehaviour
{
public float speed = 3.0f;
private float boostTimer;
private bool boosting;
public int maxHealth = 5;
public GameObject projectilePrefab;
public int Score;
int Cog;
public int Book;
public TextMeshProUGUI scoreText;
public TextMeshProUGUI CogText;
public TextMeshProUGUI BookText;
public GameObject winTextObject;
public GameObject loseTextObject;
public GameObject LevelOneTextObject;
public GameObject BackgroundMusicObject;
public GameObject WinSoundObject;
public GameObject LoseSoundObject;
private static int Level = 1;
public AudioClip throwSound;
public AudioClip hitSound;
public AudioClip collectedClip;
public AudioClip splashSound;
public AudioClip reloadSound;
public AudioClip pageSound;
public int health { get { return currentHealth; }}
int currentHealth;
public float timeInvincible = 2.0f;
bool isInvincible;
float invincibleTimer;
Rigidbody2D rigidbody2d;
float horizontal;
float vertical;
public ParticleSystem HealthIncrease;
public ParticleSystem HealthDecrease;
Animator animator;
Vector2 lookDirection = new Vector2(1,0);
AudioSource audioSource;
public bool gameOver = false;
public static bool staticVar = false;
// Start is called before the first frame update
void Start()
{
rigidbody2d = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
currentHealth = maxHealth;
audioSource = GetComponent<AudioSource>();
Score = 0;
Cog = 4;
Book = 0;
SetCogText();
SetBookText();
winTextObject.SetActive(false);
loseTextObject.SetActive(false);
LevelOneTextObject.SetActive(false);
WinSoundObject.SetActive(false);
LoseSoundObject.SetActive(false);
HealthIncrease.Stop();
HealthDecrease.Stop();
speed = 3;
boostTimer = 0;
boosting = false;
}
public void ChangeScore(int scoreAmount)
{
{
Score++;
scoreText.text = "Fixed Robots: " + Score.ToString();
}
if (Level == 1)
{
if (Score == 4)
{
LevelOneTextObject.SetActive(true);
}
}
if (Level == 2)
{
if(Score == 4 && Book == 4)
{
winTextObject.SetActive(true);
speed = 0;
WinSoundObject.SetActive(true);
BackgroundMusicObject.SetActive(false);
gameOver = true;
}
}
}
// Update is called once per frame
void Update()
{
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
Vector2 move = new Vector2(horizontal, vertical);
if(!Mathf.Approximately(move.x, 0.0f) || !Mathf.Approximately(move.y, 0.0f))
{
lookDirection.Set(move.x, move.y);
lookDirection.Normalize();
}
animator.SetFloat("Look X", lookDirection.x);
animator.SetFloat("Look Y", lookDirection.y);
animator.SetFloat("Speed", move.magnitude);
if (isInvincible)
{
invincibleTimer -= Time.deltaTime;
if (invincibleTimer < 0)
isInvincible = false;
}
if(Input.GetKeyDown(KeyCode.C) && Cog >= 1)
{
Cog = Cog -1;
SetCogText();
Launch();
}
else if (Input.GetKeyDown(KeyCode.C) && Cog ==0)
{
return;
}
if (Input.GetKeyDown(KeyCode.X))
{
RaycastHit2D hit = Physics2D.Raycast(rigidbody2d.position + Vector2.up * 0.2f, lookDirection, 1.5f, LayerMask.GetMask("NPC"));
if (hit.collider != null)
{
if (Score >= 4)
{
Level = 2;
SceneManager.LoadScene(1);
Score = 4;
}
else if (Score < 4)
{
NonPlayerCharacter character = hit.collider.GetComponent<NonPlayerCharacter>();
if (character != null)
{
character.DisplayDialog();
}
}
if (Book < 4)
{
NonPlayerCharacter character = hit.collider.GetComponent<NonPlayerCharacter>();
if (character != null)
{
character.DisplayDialog();
}
}
}
}
if(boosting)
{
boostTimer += Time.deltaTime;
if(boostTimer >= 5)
{
speed = 3;
boostTimer = 0;
boosting = false;
}
}
if (currentHealth == 0)
{
loseTextObject.SetActive(true);
{
speed = 0;
LoseSoundObject.SetActive(true);
BackgroundMusicObject.SetActive(false);
gameOver = true;
}
}
if(Input.GetKeyDown(KeyCode.R))
{
if (gameOver == true)
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
}
void SetCogText()
{
if (Cog > 0)
{
CogText.text = "Cogs: " + Cog.ToString();
}
else if (Cog <= 0)
{
CogText.text = "Out of Cogs!";
}
}
void SetBookText()
{
if (Book > 0)
{
BookText.text = "Books: " + Book.ToString();
}
}
void FixedUpdate()
{
Vector2 position = rigidbody2d.position;
position.x = position.x + speed * horizontal * Time.deltaTime;
position.y = position.y + speed * vertical * Time.deltaTime;
rigidbody2d.MovePosition(position);
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Cog"))
{
Cog = Cog + 3;
PlaySound(reloadSound);
other.gameObject.SetActive(false);
SetCogText();
}
if(other.tag == "SpeedBoost")
{
boosting = true;
speed = 6;
PlaySound(splashSound);
other.gameObject.SetActive(false);
}
if(other.tag == "Book")
{
Book = Book + 1;
PlaySound(pageSound);
other.gameObject.SetActive(false);
SetBookText();
}
}
public void ChangeHealth(int amount)
{
if (amount < 0)
{
if (isInvincible)
return;
isInvincible = true;
invincibleTimer = timeInvincible;
GameObject projectileObject = Instantiate(HealthDecrease.gameObject, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
Projectile projectile = projectileObject.GetComponent<Projectile>();
PlaySound(hitSound);
}
if (amount < 5)
{
GameObject projectileObject = Instantiate(HealthIncrease.gameObject, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
}
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
UIHealthBar.instance.SetValue(currentHealth / (float)maxHealth);
}
void Launch()
{
GameObject projectileObject = Instantiate(projectilePrefab, rigidbody2d.position + Vector2.up * 0.5f, Quaternion.identity);
Projectile projectile = projectileObject.GetComponent<Projectile>();
projectile.Launch(lookDirection, 300);
animator.SetTrigger("Launch");
PlaySound(throwSound);
}
public void PlaySound(AudioClip clip)
{
audioSource.PlayOneShot(clip);
}
}
I'm trying to add a limit in a spawn objects. I want to keep the spawn object to one. but it's not working at all.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Spawn : MonoBehaviour {
public Spawn04[] pest;
public GameObject plantPest;
void Start () {
}
[System.Obsolete]
void Update () {
if(plantPest.active)
{
SpawnObjects();
}
}
void SpawnObjects()
{
int i = Random.Range(0, 100);
for(int j = 0; j < pest.Length; j++)
{
if(i >= pest[j].minProbabilityRange && i <= pest[j].maxProbabilityRange)
{
Instantiate(pest[j].spawnObject, transform.position, transform.rotation);
break;
}
if(pest[j].pestCount >= pest[j].maxNumber)
{
Destroy(this.gameObject);
}
}
}
}
[System.Serializable]
public class Spawn04
{
public GameObject spawnObject;
public int minProbabilityRange = 0;
public int maxProbabilityRange = 0;
public int maxNumber = 1;
public int pestCount = 0;
}
All you need is a counter and a variable to controlling your max count. Just remember to decrement the counter after the object is despawned.
public class Spawn : MonoBehaviour {
public Spawn04[] pest;
public GameObject plantPest;
public int maxPests = 10; // ADDED
private int pestsSpawned = 0; // ADDED
[System.Obsolete]
void Update () {
if(plantPest.active)
{
SpawnObjects();
}
}
void SpawnObjects()
{
// NEW CHECK
if (pestsSpawned < maxPests) {
int i = Random.Range(0, 100);
for(int j = 0; j < pest.Length; j++)
{
if(i >= pest[j].minProbabilityRange && i <= pest[j].maxProbabilityRange)
{
Instantiate(pest[j].spawnObject, transform.position, transform.rotation);
pestsSpawned++; // COUNT TRACKER
break;
}
}
}
}
}
Another option is using a static variable on the Spawn04 object as such:
public class Spawn : MonoBehaviour {
public Spawn04[] pest;
public GameObject plantPest;
public int maxPests = 10; // ADDED
[System.Obsolete]
void Update () {
if(plantPest.active)
{
SpawnObjects();
}
}
void SpawnObjects()
{
// NEW CHECK
if (Spawn04.spawnCount <= maxPests) {
int i = Random.Range(0, 100);
for(int j = 0; j < pest.Length; j++)
{
if(i >= pest[j].minProbabilityRange && i <= pest[j].maxProbabilityRange)
{
Instantiate(pest[j].spawnObject, transform.position, transform.rotation);
Spawn04.spawnCount++; // COUNT TRACKER
break;
}
}
}
}
}
[System.Serializable]
public class Spawn04
{
public GameObject spawnObject;
public int minProbabilityRange = 0;
public int maxProbabilityRange = 0;
public static int spawnCount = 0; // ADDED
}
Hope this gives some inspiration on how to address this issue.
I have completed a tutorial on how to make a memory card, everything works great, I can play the game and match all the cards (20 or 30 or 40 for different categories cause I have 6 of them) and I added a timer. I can even reset the game and start all over, and all the cards are randomly sorted out.
But I want to go beyond the tutorial and put some sound effects in the game to make it more fun. I get that you can play sounds on mouse clicks and stuff, but I want to play sounds when specific cards are revealed. Duck card appears and you hear a quacking sound or his name. I'm a beginner and I don't know how to add it.
I'm not sure if I would start a new C# script or add to my existing (PictureManager) script or (Picture) script.
Any help would be appreciated. Thank you. These are my (PictureManager) and (Picture) script for the game.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PictureManager : MonoBehaviour
{
public Picture PicturePrefab;
public Transform PicSpawnPosition;
public Vector2 StartPosition = new Vector2(-2.15f, 3.62f);
public AudioSource WinSound;
public AudioSource BgSound;
[Space]
[Header("End Game Screen")]
public GameObject EndGamePanel;
public GameObject NewBestScoreText;
public GameObject YourScoreText;
public GameObject EndTimeText;
/*to rremove
public List<AudioClip> Vegetabels = new List<AudioClip>();
private AudioSource audioSource;
to remove*/
public enum GameState
{
NoAction,
MovingOnPositions,
DeletingPuzzles,
FlipBack,
Checking,
GameEnd
};
public enum PuzzleState
{
PuzzleRotating,
CanRotate,
};
public enum RevealedState
{
NoRevealed,
OneRevealed,
TwoRevealed
};
[HideInInspector]
public GameState CurrentGameState;
[HideInInspector]
public PuzzleState CurrentPuzzleState;
[HideInInspector]
public RevealedState PuzzleRevealedNumber;
[HideInInspector]
public List<Picture> PictureList;
private Vector2 _offset = new Vector2(1.42f, 1.52f);
private Vector2 _offsetFor15Pairs = new Vector2(1.08f, 1.22f);
private Vector2 _offsetFor20Pairs = new Vector2(1.08f, 1.0f);
private Vector3 _newScaleDown = new Vector3(0.9f, 0.9f, 0.001f);
private List<Material> _materialList = new List<Material>();
private List<string> _texturePathList = new List<string>();
private Material _firstMaterial;
private string _firstTexturePath;
private int _firstRevealedPic;
private int _secondRevealedPic;
private int _revealedPicNumber = 0;
private int _picToDestroy1;
private int _picToDestroy2;
private bool _corutineStarted = false;
private int _pairNumbers;
private int _removedPairs;
private Timer _gameTimer;
void Start()
{
//BgSound.Play();
CurrentGameState = GameState.NoAction;
CurrentPuzzleState = PuzzleState.CanRotate;
PuzzleRevealedNumber = RevealedState.NoRevealed;
_revealedPicNumber = 0;
_firstRevealedPic = -1;
_secondRevealedPic = -1;
_removedPairs = 0;
_pairNumbers = (int)GameSettings.Instance.GetPairNumber();
_gameTimer = GameObject.Find("Main Camera").GetComponent<Timer>();
LoadMaterials();
if(GameSettings.Instance.GetPairNumber()== GameSettings.EPairNumber.E10Pairs)
{
CurrentGameState = GameState.MovingOnPositions;
SpwanPictureMesh(4, 5, StartPosition, _offset, false);
MovePicture(4, 5, StartPosition, _offset);
}
else if (GameSettings.Instance.GetPairNumber() == GameSettings.EPairNumber.E15Pairs)
{
CurrentGameState = GameState.MovingOnPositions;
SpwanPictureMesh(5, 6, StartPosition, _offset, false);
MovePicture(5, 6, StartPosition, _offsetFor15Pairs);
}
else if (GameSettings.Instance.GetPairNumber() == GameSettings.EPairNumber.E20Pairs)
{
CurrentGameState = GameState.MovingOnPositions;
SpwanPictureMesh(5, 8, StartPosition, _offset, true);
MovePicture(5, 8, StartPosition, _offsetFor20Pairs);
}
}
public void CheckPicture()
{
CurrentGameState = GameState.Checking;
_revealedPicNumber = 0;
for(int id = 0; id < PictureList.Count; id++)
{
if(PictureList[id].Revealed && _revealedPicNumber < 2)
{
if(_revealedPicNumber == 0)
{
_firstRevealedPic = id;
_revealedPicNumber++;
//audioSource.PlayOneShot(Vegetabels[id]);
}
else if (_revealedPicNumber == 1)
{
_secondRevealedPic = id;
_revealedPicNumber++;
}
}
if (_revealedPicNumber == 2)
{
if (PictureList[_firstRevealedPic].GetIndex() == PictureList[_secondRevealedPic].GetIndex() && _firstRevealedPic != _secondRevealedPic)
{
CurrentGameState = GameState.DeletingPuzzles;
_picToDestroy1 = _firstRevealedPic;
_picToDestroy2 = _secondRevealedPic;
}
else
{
CurrentGameState = GameState.FlipBack;
}
}
}
CurrentPuzzleState = PictureManager.PuzzleState.CanRotate;
if(CurrentGameState == GameState.Checking)
{
CurrentGameState = GameState.NoAction;
}
}
private void DestroyPicture()
{
PuzzleRevealedNumber = RevealedState.NoRevealed;
PictureList[_picToDestroy1].Deactivate();
PictureList[_picToDestroy2].Deactivate();
_revealedPicNumber = 0;
_removedPairs++;
CurrentGameState = GameState.NoAction;
CurrentPuzzleState = PuzzleState.CanRotate;
}
private IEnumerator FlipBack()
{
_corutineStarted = true;
yield return new WaitForSeconds(0.5f);
PictureList[_firstRevealedPic].FlipBack();
PictureList[_secondRevealedPic].FlipBack();
PictureList[_firstRevealedPic].Revealed = false;
PictureList[_secondRevealedPic].Revealed = false;
PuzzleRevealedNumber = RevealedState.NoRevealed;
CurrentGameState = GameState.NoAction;
_corutineStarted = false;
}
private void LoadMaterials()
{
var materialFilePath = GameSettings.Instance.GetMaterialDirectoryName();
var textureFilePath = GameSettings.Instance.GetPuzzleCategoryTextureDirectoryName();
var pairNumber = (int)GameSettings.Instance.GetPairNumber();
const string matBaseName = "Pic";
var firstMaterialName = "Back";
for(var index = 1; index <= pairNumber; index++)
{
var currentFilePath = materialFilePath + matBaseName + index;
Material mat = Resources.Load(currentFilePath, typeof(Material)) as Material;
_materialList.Add(mat);
var currentTextureFilePath = textureFilePath + matBaseName + index;
_texturePathList.Add(currentTextureFilePath);
}
_firstTexturePath = textureFilePath + firstMaterialName;
_firstMaterial = Resources.Load(materialFilePath + firstMaterialName, typeof(Material)) as Material;
}
void Update()
{
if (PauseMenu.isPaused == false) {
if (CurrentGameState == GameState.DeletingPuzzles)
{
if(CurrentPuzzleState == PuzzleState.CanRotate)
{
DestroyPicture();
CheckGameEnd();
}
}
if (CurrentGameState == GameState.FlipBack)
{
if(CurrentPuzzleState == PuzzleState.CanRotate && _corutineStarted == false)
{
StartCoroutine(FlipBack());
}
}
if(CurrentGameState == GameState.GameEnd)
{
if(PictureList[_firstRevealedPic].gameObject.activeSelf == false &&
PictureList[_secondRevealedPic].gameObject.activeSelf == false &&
EndGamePanel.activeSelf == false)
{
ShowEndGameInformation();
if (GameSettings.Instance.IsSoundEffectMutedPermanently() == false)
WinSound.Play();
//BgSound.Pause();
}
}
}
}
private bool CheckGameEnd()
{
if(_removedPairs == _pairNumbers && CurrentGameState != GameState.GameEnd)
{
CurrentGameState = GameState.GameEnd;
_gameTimer.StopTimer();
Config.PlaceScoreOnBorad(_gameTimer.GetCurrentTime());
}
return (CurrentGameState == GameState.GameEnd);
}
private void ShowEndGameInformation()
{
EndGamePanel.SetActive(true);
if(Config.IsBestScore())
{
NewBestScoreText.SetActive(true);
YourScoreText.SetActive(false);
}
else
{
NewBestScoreText.SetActive(false);
YourScoreText.SetActive(true);
}
var timer = _gameTimer.GetCurrentTime();
var minutes = Mathf.Floor(timer / 60);
var seconds = Mathf.RoundToInt(timer % 60);
var newText = minutes.ToString("00") + ":" + seconds.ToString("00");
EndTimeText.GetComponent<Text>().text = newText;
}
private void SpwanPictureMesh(int rows, int columns, Vector2 Pos, Vector2 offset, bool scaleDown)
{
for(int col = 0; col < columns; col++)
{
for(int row = 0; row < rows; row++)
{
var tempPicture = (Picture)Instantiate(PicturePrefab, PicSpawnPosition.position, PicturePrefab.transform.rotation);
if(scaleDown)
{
tempPicture.transform.localScale = _newScaleDown;
}
tempPicture.name = tempPicture.name + 'c' + col + 'r' + row;
PictureList.Add(tempPicture);
}
}
ApplyTextures();
}
public void ApplyTextures()
{
var rndMatIndex = Random.Range(0, _materialList.Count);
var AppliedTimes = new int[_materialList.Count];
for(int i = 0; i< _materialList.Count; i++)
{
AppliedTimes[i] = 0;
}
foreach(var o in PictureList)
{
var randPrevious = rndMatIndex;
var counter = 0;
var forceMat = false;
while(AppliedTimes[rndMatIndex] >= 2 || ((randPrevious == rndMatIndex) && !forceMat))
{
rndMatIndex = Random.Range(0, _materialList.Count);
counter++;
if(counter > 100)
{
for (var j = 0; j < _materialList.Count; j++)
{
if(AppliedTimes[j] < 2)
{
rndMatIndex = j;
forceMat = true;
}
}
if (forceMat == false)
return;
}
}
o.SetFirstMaterial(_firstMaterial, _firstTexturePath);
o.ApplyFirstMaterial();
o.SetSecondMaterial(_materialList[rndMatIndex], _texturePathList[rndMatIndex]);
o.SetIndex(rndMatIndex);
o.Revealed = false;
AppliedTimes[rndMatIndex] += 1;
forceMat = false;
}
}
private void MovePicture(int rows, int columns, Vector2 pos, Vector2 offset)
{
var index = 0;
for(var col = 0; col < columns; col++)
{
for(int row = 0; row < rows; row++)
{
var targetPosition = new Vector3((pos.x + (offset.x * row)), (pos.y - (offset.y * col)), 0.0f);
StartCoroutine(MoveToPosition(targetPosition, PictureList[index]));
index++;
}
}
}
private IEnumerator MoveToPosition(Vector3 target, Picture obj)
{
var randomDis = 7;
while(obj.transform.position !=target)
{
obj.transform.position = Vector3.MoveTowards(obj.transform.position, target, randomDis * Time.deltaTime);
yield return 0;
}
}
}
----------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Picture : MonoBehaviour
{
public AudioClip PressSound;
private Material _firstMaterial;
private Material _secondMaterial;
private Quaternion _currentRotation;
[HideInInspector] public bool Revealed = false;
private PictureManager _pictureManager;
private bool _clicked = false;
private int _index;
private AudioSource _audio;
public void SetIndex(int id)
{
_index = id;
}
public int GetIndex()
{
return _index;
}
void Start()
{
Revealed = false;
_clicked = false;
_pictureManager = GameObject.Find("[PictureManager]").GetComponent<PictureManager>();
_currentRotation = gameObject.transform.rotation;
_audio = GetComponent<AudioSource>();
_audio.clip = PressSound;
}
void Update()
{
}
private void OnMouseDown()
{
if(_clicked == false)
{
if (PauseMenu.isPaused == false)
{
_pictureManager.CurrentPuzzleState = PictureManager.PuzzleState.PuzzleRotating;
if (GameSettings.Instance.IsSoundEffectMutedPermanently() == false)
_audio.Play();
StartCoroutine(LoopRotation(45, false));
_clicked = true;
}
}
}
public void FlipBack()
{
if (gameObject.activeSelf)
{
_pictureManager.CurrentPuzzleState = PictureManager.PuzzleState.PuzzleRotating;
Revealed = false;
/*if (GameSettings.Instance.IsSoundEffectMutedPermanently() == false)
_audio.Play();*/
StartCoroutine(LoopRotation(45, true));
}
}
IEnumerator LoopRotation(float angle, bool FirstMat)
{
var rot = 0f;
const float dir = 1f;
const float rotSpeed = 180.0f;
const float rotSpeed1 = 90.0f;
var startAngle = angle;
var assigned = false;
if(FirstMat)
{
while(rot < angle)
{
var step = Time.deltaTime * rotSpeed1;
gameObject.GetComponent<Transform>().Rotate(new Vector3(0, 2, 0) * step * dir);
if(rot >= (startAngle - 2) && assigned == false)
{
ApplyFirstMaterial();
assigned = true;
}
rot += (1 * step * dir);
yield return null;
}
}
else
{
while (angle > 0)
{
float step = Time.deltaTime * rotSpeed;
gameObject.GetComponent<Transform>().Rotate(new Vector3(0, 2, 0) * step * dir);
angle -= (1 * step * dir);
yield return null;
}
}
gameObject.GetComponent<Transform>().rotation = _currentRotation;
if (!FirstMat)
{
Revealed = true;
ApplySecondMaterial();
_pictureManager.CheckPicture();
}
else
{
_pictureManager.PuzzleRevealedNumber = PictureManager.RevealedState.NoRevealed;
_pictureManager.CurrentPuzzleState = PictureManager.PuzzleState.CanRotate;
}
_clicked = false;
}
public void SetFirstMaterial(Material mat, string texturePath)
{
_firstMaterial = mat;
_firstMaterial.mainTexture = Resources.Load(texturePath, typeof(Texture2D)) as Texture2D;
}
public void SetSecondMaterial(Material mat, string texturePath)
{
_secondMaterial = mat;
_secondMaterial.mainTexture = Resources.Load(texturePath, typeof(Texture2D)) as Texture2D;
}
public void ApplyFirstMaterial()
{
gameObject.GetComponent<Renderer>().material = _firstMaterial;
}
public void ApplySecondMaterial()
{
gameObject.GetComponent<Renderer>().material = _secondMaterial;
}
public void Deactivate()
{
StartCoroutine(DeactivateCorutine());
}
private IEnumerator DeactivateCorutine()
{
Revealed = false;
yield return new WaitForSeconds(1f);
gameObject.SetActive(false);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PictureManager : MonoBehaviour
{
public Picture PicturePrefab;
public Transform PicSpawnPosition;
public Vector2 StartPosition = new Vector2(-2.15f, 3.62f);
public AudioSource WinSound;
public AudioSource BgSound;
[Space]
[Header("End Game Screen")]
public GameObject EndGamePanel;
public GameObject NewBestScoreText;
public GameObject YourScoreText;
public GameObject EndTimeText;
/*to rremove
public List<AudioClip> Vegetabels = new List<AudioClip>();
private AudioSource audioSource;
to remove*/
public enum GameState
{
NoAction,
MovingOnPositions,
DeletingPuzzles,
FlipBack,
Checking,
GameEnd
};
public enum PuzzleState
{
PuzzleRotating,
CanRotate,
};
public enum RevealedState
{
NoRevealed,
OneRevealed,
TwoRevealed
};
[HideInInspector]
public GameState CurrentGameState;
[HideInInspector]
public PuzzleState CurrentPuzzleState;
[HideInInspector]
public RevealedState PuzzleRevealedNumber;
[HideInInspector]
public List<Picture> PictureList;
private Vector2 _offset = new Vector2(1.42f, 1.52f);
private Vector2 _offsetFor15Pairs = new Vector2(1.08f, 1.22f);
private Vector2 _offsetFor20Pairs = new Vector2(1.08f, 1.0f);
private Vector3 _newScaleDown = new Vector3(0.9f, 0.9f, 0.001f);
private List<Material> _materialList = new List<Material>();
private List<string> _texturePathList = new List<string>();
private Material _firstMaterial;
private string _firstTexturePath;
private int _firstRevealedPic;
private int _secondRevealedPic;
private int _revealedPicNumber = 0;
private int _picToDestroy1;
private int _picToDestroy2;
private bool _corutineStarted = false;
private int _pairNumbers;
private int _removedPairs;
private Timer _gameTimer;
void Start()
{
//BgSound.Play();
CurrentGameState = GameState.NoAction;
CurrentPuzzleState = PuzzleState.CanRotate;
PuzzleRevealedNumber = RevealedState.NoRevealed;
_revealedPicNumber = 0;
_firstRevealedPic = -1;
_secondRevealedPic = -1;
_removedPairs = 0;
_pairNumbers = (int)GameSettings.Instance.GetPairNumber();
_gameTimer = GameObject.Find("Main Camera").GetComponent<Timer>();
LoadMaterials();
if(GameSettings.Instance.GetPairNumber()== GameSettings.EPairNumber.E10Pairs)
{
CurrentGameState = GameState.MovingOnPositions;
SpwanPictureMesh(4, 5, StartPosition, _offset, false);
MovePicture(4, 5, StartPosition, _offset);
}
else if (GameSettings.Instance.GetPairNumber() == GameSettings.EPairNumber.E15Pairs)
{
CurrentGameState = GameState.MovingOnPositions;
SpwanPictureMesh(5, 6, StartPosition, _offset, false);
MovePicture(5, 6, StartPosition, _offsetFor15Pairs);
}
else if (GameSettings.Instance.GetPairNumber() == GameSettings.EPairNumber.E20Pairs)
{
CurrentGameState = GameState.MovingOnPositions;
SpwanPictureMesh(5, 8, StartPosition, _offset, true);
MovePicture(5, 8, StartPosition, _offsetFor20Pairs);
}
}
public void CheckPicture()
{
CurrentGameState = GameState.Checking;
_revealedPicNumber = 0;
for(int id = 0; id < PictureList.Count; id++)
{
if(PictureList[id].Revealed && _revealedPicNumber < 2)
{
if(_revealedPicNumber == 0)
{
_firstRevealedPic = id;
_revealedPicNumber++;
//audioSource.PlayOneShot(Vegetabels[id]);
}
else if (_revealedPicNumber == 1)
{
_secondRevealedPic = id;
_revealedPicNumber++;
}
}
if (_revealedPicNumber == 2)
{
if (PictureList[_firstRevealedPic].GetIndex() == PictureList[_secondRevealedPic].GetIndex() && _firstRevealedPic != _secondRevealedPic)
{
CurrentGameState = GameState.DeletingPuzzles;
_picToDestroy1 = _firstRevealedPic;
_picToDestroy2 = _secondRevealedPic;
}
else
{
CurrentGameState = GameState.FlipBack;
}
}
}
CurrentPuzzleState = PictureManager.PuzzleState.CanRotate;
if(CurrentGameState == GameState.Checking)
{
CurrentGameState = GameState.NoAction;
}
}
private void DestroyPicture()
{
PuzzleRevealedNumber = RevealedState.NoRevealed;
PictureList[_picToDestroy1].Deactivate();
PictureList[_picToDestroy2].Deactivate();
_revealedPicNumber = 0;
_removedPairs++;
CurrentGameState = GameState.NoAction;
CurrentPuzzleState = PuzzleState.CanRotate;
}
private IEnumerator FlipBack()
{
_corutineStarted = true;
yield return new WaitForSeconds(0.5f);
PictureList[_firstRevealedPic].FlipBack();
PictureList[_secondRevealedPic].FlipBack();
PictureList[_firstRevealedPic].Revealed = false;
PictureList[_secondRevealedPic].Revealed = false;
PuzzleRevealedNumber = RevealedState.NoRevealed;
CurrentGameState = GameState.NoAction;
_corutineStarted = false;
}
private void LoadMaterials()
{
var materialFilePath = GameSettings.Instance.GetMaterialDirectoryName();
var textureFilePath = GameSettings.Instance.GetPuzzleCategoryTextureDirectoryName();
var pairNumber = (int)GameSettings.Instance.GetPairNumber();
const string matBaseName = "Pic";
var firstMaterialName = "Back";
for(var index = 1; index <= pairNumber; index++)
{
var currentFilePath = materialFilePath + matBaseName + index;
Material mat = Resources.Load(currentFilePath, typeof(Material)) as Material;
_materialList.Add(mat);
var currentTextureFilePath = textureFilePath + matBaseName + index;
_texturePathList.Add(currentTextureFilePath);
}
_firstTexturePath = textureFilePath + firstMaterialName;
_firstMaterial = Resources.Load(materialFilePath + firstMaterialName, typeof(Material)) as Material;
}
void Update()
{
if (PauseMenu.isPaused == false) {
if (CurrentGameState == GameState.DeletingPuzzles)
{
if(CurrentPuzzleState == PuzzleState.CanRotate)
{
DestroyPicture();
CheckGameEnd();
}
}
if (CurrentGameState == GameState.FlipBack)
{
if(CurrentPuzzleState == PuzzleState.CanRotate && _corutineStarted == false)
{
StartCoroutine(FlipBack());
}
}
if(CurrentGameState == GameState.GameEnd)
{
if(PictureList[_firstRevealedPic].gameObject.activeSelf == false &&
PictureList[_secondRevealedPic].gameObject.activeSelf == false &&
EndGamePanel.activeSelf == false)
{
ShowEndGameInformation();
if (GameSettings.Instance.IsSoundEffectMutedPermanently() == false)
WinSound.Play();
//BgSound.Pause();
}
}
}
}
private bool CheckGameEnd()
{
if(_removedPairs == _pairNumbers && CurrentGameState != GameState.GameEnd)
{
CurrentGameState = GameState.GameEnd;
_gameTimer.StopTimer();
Config.PlaceScoreOnBorad(_gameTimer.GetCurrentTime());
}
return (CurrentGameState == GameState.GameEnd);
}
private void ShowEndGameInformation()
{
EndGamePanel.SetActive(true);
if(Config.IsBestScore())
{
NewBestScoreText.SetActive(true);
YourScoreText.SetActive(false);
}
else
{
NewBestScoreText.SetActive(false);
YourScoreText.SetActive(true);
}
var timer = _gameTimer.GetCurrentTime();
var minutes = Mathf.Floor(timer / 60);
var seconds = Mathf.RoundToInt(timer % 60);
var newText = minutes.ToString("00") + ":" + seconds.ToString("00");
EndTimeText.GetComponent<Text>().text = newText;
}
private void SpwanPictureMesh(int rows, int columns, Vector2 Pos, Vector2 offset, bool scaleDown)
{
for(int col = 0; col < columns; col++)
{
for(int row = 0; row < rows; row++)
{
var tempPicture = (Picture)Instantiate(PicturePrefab, PicSpawnPosition.position, PicturePrefab.transform.rotation);
if(scaleDown)
{
tempPicture.transform.localScale = _newScaleDown;
}
tempPicture.name = tempPicture.name + 'c' + col + 'r' + row;
PictureList.Add(tempPicture);
}
}
ApplyTextures();
}
public void ApplyTextures()
{
var rndMatIndex = Random.Range(0, _materialList.Count);
var AppliedTimes = new int[_materialList.Count];
for(int i = 0; i< _materialList.Count; i++)
{
AppliedTimes[i] = 0;
}
foreach(var o in PictureList)
{
var randPrevious = rndMatIndex;
var counter = 0;
var forceMat = false;
while(AppliedTimes[rndMatIndex] >= 2 || ((randPrevious == rndMatIndex) && !forceMat))
{
rndMatIndex = Random.Range(0, _materialList.Count);
counter++;
if(counter > 100)
{
for (var j = 0; j < _materialList.Count; j++)
{
if(AppliedTimes[j] < 2)
{
rndMatIndex = j;
forceMat = true;
}
}
if (forceMat == false)
return;
}
}
o.SetFirstMaterial(_firstMaterial, _firstTexturePath);
o.ApplyFirstMaterial();
o.SetSecondMaterial(_materialList[rndMatIndex], _texturePathList[rndMatIndex]);
o.SetIndex(rndMatIndex);
o.Revealed = false;
AppliedTimes[rndMatIndex] += 1;
forceMat = false;
}
}
private void MovePicture(int rows, int columns, Vector2 pos, Vector2 offset)
{
var index = 0;
for(var col = 0; col < columns; col++)
{
for(int row = 0; row < rows; row++)
{
var targetPosition = new Vector3((pos.x + (offset.x * row)), (pos.y - (offset.y * col)), 0.0f);
StartCoroutine(MoveToPosition(targetPosition, PictureList[index]));
index++;
}
}
}
private IEnumerator MoveToPosition(Vector3 target, Picture obj)
{
var randomDis = 7;
while(obj.transform.position !=target)
{
obj.transform.position = Vector3.MoveTowards(obj.transform.position, target, randomDis * Time.deltaTime);
yield return 0;
}
}
}
Recently I have changed my code from being a non-animated sprite to being animated. Now I'm having some trouble with the angle of the image.
When I turn I can see that the angle works because the fireballs are shooting in the correct direction, but the animated sprite is not. I have tried using base.Angle in the SpriteBatch.Draw method but it didn't take 5 arguments.
This is my code:
class Dragon : MovingGameObj
{
public Dragon()
{
framerate = 14;
timetolive = 3000;
repeat = 1;
timer = 0;
framesX = 1;
framesY = 2;
frameSize = 100;
alive = true;
activeframe = 0;
MaxSpeed = 2.5F;
FireballPower = 0;
prevKs = Keyboard.GetState();
prevKs2 = Keyboard.GetState();
Life = 100F;
Kills = 0;
Angle = -(float)(Math.PI / 2);
}
public bool alive;
private int activeframe;
int tmpTid = 0;
public int framerate { set; get; }
public int timetolive { set; get; }
public int repeat { set; get; }
public int framesX { set; get; }
public int framesY { set; get; }
public int timer { set; get; }
public int frameSize { set; get; }
public bool Enemy { get; set; }
public float MaxSpeed { get; set; }
public float FireballPower { get; set; }
public int WeaponType { get; set; }
public bool FireballFired { get; set; }
public float Life { get; set; }
public int Kills { get; set; }
protected KeyboardState prevKs;
protected KeyboardState prevKs2;
public void Respawn()
{
Life = 100F;
Random randomerare = new Random();
Position = new Vector2(randomerare.Next(1000), randomerare.Next(1000));
Angle = 0F;
}
public override void Update(GameTime gameTime)
{
KeyboardState ks = Keyboard.GetState();
KeyboardState ks2 = Keyboard.GetState();
#region Player 1
if (Enemy == false)
{
if (ks.IsKeyDown(Keys.Up))
{
if (Speed < 0) Speed = 0;
if (Speed < MaxSpeed) Speed = Speed * 1.005F + 0.01F;
else Speed = MaxSpeed;
}
if (ks.IsKeyDown(Keys.Down))
{
if (Speed > -1.0F) Speed -= 0.04F;
else Speed = -1.0F;
}
if (ks.IsKeyUp(Keys.Down) && ks.IsKeyUp(Keys.Up) && Speed > 0)
{
Speed -= 0.01F;
if (Speed <= 0) Speed = 0;
}
if (ks.IsKeyUp(Keys.Down) && ks.IsKeyUp(Keys.Up) && Speed < 0)
{
Speed += 0.01F;
if (Speed >= 0) Speed = 0;
}
if (ks.IsKeyUp(Keys.Left))
{
Angle += 0.02F;
}
if (ks.IsKeyUp(Keys.Right))
{
Angle -= 0.02F;
}
if (ks.IsKeyDown(Keys.Space))
{
if (FireballPower < 100)
FireballPower += 0.5F;
else
FireballPower = 100;
}
if (ks.IsKeyUp(Keys.Space) && prevKs.IsKeyDown(Keys.Space))
{
//FireballPower = 0;
FireballFired = true;
}
}
#endregion
#region Player 2
if (Enemy == true)
{
if (ks2.IsKeyDown(Keys.W))
{
if (Speed < 0) Speed = 0;
if (Speed < MaxSpeed) Speed = Speed * 1.005F + 0.01F;
else Speed = MaxSpeed;
}
if (ks2.IsKeyDown(Keys.S))
{
if (Speed > -1.0F) Speed -= 0.04F;
else Speed = -1.0F;
}
if (ks2.IsKeyUp(Keys.S) && ks2.IsKeyUp(Keys.W) && Speed > 0)
{
Speed -= 0.01F;
if (Speed <= 0) Speed = 0;
}
if (ks2.IsKeyUp(Keys.S) && ks2.IsKeyUp(Keys.W) && Speed < 0)
{
Speed += 0.01F;
if (Speed >= 0) Speed = 0;
}
if (ks2.IsKeyUp(Keys.A))
{
Angle += 0.02F;
}
if (ks2.IsKeyUp(Keys.D))
{
Angle -= 0.02F;
}
if (ks2.IsKeyDown(Keys.LeftControl))
{
if (FireballPower < 100)
FireballPower += 0.5F;
else
FireballPower = 100;
}
if (ks2.IsKeyUp(Keys.LeftControl) && prevKs2.IsKeyDown(Keys.LeftControl))
{
//FireballPower = 0;
FireballFired = true;
}
}
#endregion
prevKs = ks;
prevKs2 = ks2;
Direction = new Vector2((float)Math.Cos(Angle), (float)Math.Sin(Angle));
timer += gameTime.ElapsedGameTime.Milliseconds;
if (timer > timetolive)
{
alive = false;
}
tmpTid += gameTime.ElapsedGameTime.Milliseconds;
if (tmpTid > (1000 / framerate))
{
activeframe += 1;
tmpTid = 0;
if (activeframe > (framesX * framesY))
{
activeframe = 0;
}
}
base.Update(gameTime);
}
public override void Draw(SpriteBatch spriteBatch)
{
Rectangle tmp = new Rectangle(activeframe%framesX*frameSize,activeframe/framesY*frameSize,frameSize,frameSize);
spriteBatch.Draw(base.Gfx,base.Position, tmp,Color.White);
}
}
Try using this SpriteBatch.Draw() overload:
spriteBatch.Draw(base.Gfx, base.Position, tmp, Color.White, Angle, Vector2.Zero, 1f, SpriteEffects.None, 0f);