asset integration 50%

This commit is contained in:
2026-03-29 02:27:55 +05:30
parent 3108262326
commit b8ce9120d5
1691 changed files with 1192616 additions and 262 deletions
+30 -1
View File
@@ -9,6 +9,8 @@ public class Ball : MonoBehaviour
public float wallStuckFixForce = 1f;
public float maxWallStuckVelocity = 5f;
public LayerMask wallLayerMask;
public float distToGoal;
public float nearGoalThreshold = 2.5f;
void Awake()
{
rb = GetComponent<Rigidbody2D>();
@@ -34,7 +36,23 @@ public class Ball : MonoBehaviour
void Update()
{
WallDetection();
CheckNearGoal();
}
void CheckNearGoal(){
Goal[] goals = FindObjectsByType<Goal>(FindObjectsSortMode.None);
float closestDist = float.MaxValue;
foreach(Goal goal in goals){
float dist = Vector3.Distance(transform.position, goal.transform.position);
if(dist < closestDist){
closestDist = dist;
}
}
distToGoal = closestDist;
AudioManager.instance.SetIsBallNearGoal(distToGoal < nearGoalThreshold);
}
void OnCollisionEnter2D(Collision2D collision)
{
float otherSpeed = collision.relativeVelocity.magnitude;
@@ -67,7 +85,18 @@ public class Ball : MonoBehaviour
if (touchingB) {
rb.AddForce(Vector2.up *otherSpeed * wallStuckFixForce * velocityMult );
}
float maxVolSpeed =5f;
float vol = Mathf.Clamp01(otherSpeed / maxVolSpeed);
if(collision.collider.CompareTag("wall")){
AudioManager.instance.PlayWallHit(vol);
}
else if(collision.collider.CompareTag("Puck")){
AudioManager.instance.PlayBallHit(vol);
}
}
void WallDetection(){
+48
View File
@@ -0,0 +1,48 @@
using UnityEngine;
using DG.Tweening;
[RequireComponent(typeof(Camera))]
public class CameraEffects : MonoBehaviour
{
public static CameraEffects instance;
Camera cam;
[SerializeField]private float stretchFactor = 0;
[SerializeField]private bool isBeingStretched = false;
[SerializeField]private float minFov = 5;
[SerializeField]private float maxFov = 10;
[SerializeField]private float fovSpeed = 10;
[SerializeField] private float bounceDuration = 0.35f;
[SerializeField] private float bounceElasticity = 0.7f;
[SerializeField] private float bounceOvershoot = 0.2f;
void Awake()
{
instance = this;
cam = Camera.main;
}
void Update()
{
if(isBeingStretched){
float targetFov = minFov + stretchFactor * (maxFov - minFov);
cam.orthographicSize = Mathf.Lerp(cam.orthographicSize, targetFov, Time.deltaTime * fovSpeed);
}
}
public void SetStretchFactor(float stretchFactor){
this.stretchFactor = stretchFactor;
isBeingStretched = true;
}
public void ReleaseStretchFactor(){
stretchFactor = 0;
isBeingStretched = false;
cam.DOOrthoSize(minFov, bounceDuration)
.SetEase(Ease.OutElastic, bounceElasticity, bounceOvershoot)
.OnComplete(() => {
stretchFactor = 0;
});
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0c056bc55f8e80b408b5d45af7e7ac02
+34 -9
View File
@@ -3,6 +3,7 @@ using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;
using UnityEngine.UI;
using DG.Tweening;
public class GameCanvas : MonoBehaviour
@@ -20,9 +21,11 @@ public class GameCanvas : MonoBehaviour
public Image turnTimerSliderTransform;
public Color redColor = Color.red;
public Color blueColor = Color.blue;
public TMP_Text blueTurnTimer;
[FormerlySerializedAs("txtTurnTimer")] public TMP_Text redTurnTimer;
public TMP_Text txtWhosTurn;
public TMP_Text txtTurnTimer;
public Image turnTimerRound;
public Image blueTurnTimerRound;
[FormerlySerializedAs("turnTimerRound")] public Image redTurnTimerRound;
public GameObject waitingForOpponentPanel;
@@ -54,8 +57,27 @@ public class GameCanvas : MonoBehaviour
}
turnTimerSliderTransform.transform.localScale = new Vector3(turnTimerFillAmount, 1, 1);
txtTurnTimer.text = (GameManager.instance.turnTimer - GameManager.instance.turnTimerCounter).ToString("F0");
turnTimerRound.fillAmount = turnTimerFillAmount;
string timerString = (GameManager.instance.turnTimer - GameManager.instance.turnTimerCounter).ToString("F0");
if (GameManager.instance.SelectedTeam == Team.Red)
{
if (redTurnTimer != null) redTurnTimer.text = ":"+timerString;
if (blueTurnTimer != null) blueTurnTimer.text = string.Empty;
}
else
{
if (blueTurnTimer != null) blueTurnTimer.text = ":"+timerString;
if (redTurnTimer != null) redTurnTimer.text = string.Empty;
}
if (GameManager.instance.SelectedTeam == Team.Red)
{
if (redTurnTimerRound != null) redTurnTimerRound.fillAmount = turnTimerFillAmount;
if (blueTurnTimerRound != null) blueTurnTimerRound.fillAmount = 0f;
}
else
{
if (blueTurnTimerRound != null) blueTurnTimerRound.fillAmount = turnTimerFillAmount;
if (redTurnTimerRound != null) redTurnTimerRound.fillAmount = 0f;
}
}
void SwitchTeams(){
@@ -63,11 +85,14 @@ public class GameCanvas : MonoBehaviour
Color newColor = GameManager.instance.SelectedTeam == Team.Red ? redColor : blueColor;
turnTimerSliderTransform.DOColor(newColor, 0.5f);
txtWhosTurn.DOFade(0, 0.25f).OnComplete(() => {
txtWhosTurn.text = isMyTurn ? "Your Turn" : "Opponent's Turn";
txtWhosTurn.DOFade(1, 0.25f);
});
if (txtWhosTurn != null)
{
txtWhosTurn.DOFade(0, 0.25f).OnComplete(() => {
txtWhosTurn.text = isMyTurn ? "Your Turn" : "Opponent's Turn";
txtWhosTurn.DOFade(1, 0.25f);
});
}
}
}
+131
View File
@@ -3,6 +3,7 @@ using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;
using TMPro;
using Mirror;
@@ -21,6 +22,8 @@ public class GameManager : NetworkBehaviour
void OnGameStartedChanged(bool oldStarted, bool newStarted){
if(newStarted){
GameCanvas.instance.HideWaitingForOpponentPanel();
if (AudioManager.instance != null)
AudioManager.instance.SetCrowdNoiseType(CrowdNoiseType.Normal);
}else{
GameCanvas.instance.ShowWaitingForOpponentPanel();
}
@@ -31,6 +34,11 @@ public class GameManager : NetworkBehaviour
void OnSelectedTeamChanged(Team oldTeam, Team newTeam){
Debug.Log($"Selected team changed from {oldTeam} to {newTeam}");
OnTeamChanged?.Invoke(newTeam);
if (!isClient || !gameStarted || oldTeam == newTeam)
return;
if (AudioManager.instance != null)
AudioManager.instance.PlayRefereeWhistle();
}
public static bool NoPuckSelected {
get{
@@ -58,6 +66,13 @@ public class GameManager : NetworkBehaviour
public TMP_Text blueScoreText;
public GameObject gameOverPanel;
public GameObject blueWon,redWon;
public CanvasGroupUtils blueTimerGroup;
[FormerlySerializedAs("timerGroup")] public CanvasGroupUtils redTimerGroup;
[Header("Timer Flash Settings")]
[Tooltip("Minimum flash speed when timer is at 5 seconds")]
public float minFlashSpeed = 10f;
[Tooltip("Maximum flash speed when timer is at 0 seconds")]
public float maxFlashSpeed = 20f;
[Header("Misc")]
public List<Puck> pucks = new List<Puck>();
@@ -251,6 +266,13 @@ public class GameManager : NetworkBehaviour
if(!gameStarted){
NetPlayer[] players = FindObjectsOfType<NetPlayer>();
#if UNITY_EDITOR
if(Input.GetKeyDown(KeyCode.Space)){
gameStarted = true;
GameCanvas.instance.HideWaitingForOpponentPanel();
Debug.Log("Game started On Server, EDITOR ONLY, DEBUG ONLY");
}
#endif
if (players.Length == 2)
{
gameStarted = true;
@@ -259,6 +281,36 @@ public class GameManager : NetworkBehaviour
}
}
}
UpdateLocalTurnTimerBeep();
UpdateTimerColor();
}
void UpdateLocalTurnTimerBeep()
{
if (!isClient || NetPlayer.localPlayer == null)
return;
if (!gameStarted || SelectedTeam != NetPlayer.localPlayer.myTeam)
{
_lastTurnTimerBeepFloor = -1;
return;
}
if (m_isMoving || turnTimerCounter >= turnTimer)
return;
float remaining = turnTimer - turnTimerCounter;
int floorSec = Mathf.FloorToInt(remaining);
if (floorSec != _lastTurnTimerBeepFloor)
{
if (_lastTurnTimerBeepFloor >= 0 && floorSec < _lastTurnTimerBeepFloor
&& AudioManager.instance != null)
AudioManager.instance.PlayTimerBeep();
_lastTurnTimerBeepFloor = floorSec;
}
}
void HandleTurnTimer(){
@@ -272,10 +324,82 @@ public class GameManager : NetworkBehaviour
}
}
float flashPhase = 0f;
float lastUpdateTime = 0f;
float lastRemainingTime = 10f;
int _lastTurnTimerBeepFloor = -1;
void UpdateTimerColor(){
float remainingTime = turnTimer - turnTimerCounter;
// Detect timer reset: if remainingTime jumped from low to high, reset phase
if(remainingTime > lastRemainingTime + 2f){
flashPhase = 0f;
lastUpdateTime = 0f;
}
lastRemainingTime = remainingTime;
CanvasGroupUtils activeTimerGroup = SelectedTeam == Team.Red ? redTimerGroup : blueTimerGroup;
CanvasGroupUtils inactiveTimerGroup = SelectedTeam == Team.Red ? blueTimerGroup : redTimerGroup;
if(inactiveTimerGroup != null){
inactiveTimerGroup.overrideColor = Color.white;
}
if(activeTimerGroup == null){
if(remainingTime >= 5f || !gameStarted){
flashPhase = 0f;
lastUpdateTime = 0f;
}
return;
}
if(remainingTime < 5f && gameStarted){
// Calculate intensity based on how close timer is to 0
// Intensity increases from 0 to 1 as timer goes from 5 to 0
float intensity = 1f - (remainingTime / 5f);
// Create flashing effect using sine wave
// Flash speed increases as timer approaches 0
float flashSpeed = Mathf.Lerp(minFlashSpeed, maxFlashSpeed, intensity);
// Update phase based on delta time and current flash speed
// This ensures smooth flashing that resets with the timer
if(lastUpdateTime > 0f){
float deltaTime = Time.time - lastUpdateTime;
flashPhase += flashSpeed * deltaTime;
} else {
// First frame in warning zone, initialize phase
flashPhase = 0f;
}
lastUpdateTime = Time.time;
float flashValue = (Mathf.Sin(flashPhase) + 1f) * 0.5f; // 0 to 1
// Combine intensity with flash for final red intensity
// As timer approaches 0, intensity increases and flash becomes more prominent
float finalRedIntensity = intensity * (0.3f + flashValue * 0.7f); // Range: intensity*0.3 to intensity*1
// Lerp between white and red based on final intensity, keeping alpha at 1
Color white = Color.white;
Color red = Color.red;
activeTimerGroup.overrideColor = Color.Lerp(white, red, finalRedIntensity);
}else{
// Reset phase when timer is above 5 seconds or game hasn't started
flashPhase = 0f;
lastUpdateTime = 0f;
activeTimerGroup.overrideColor = Color.white;
}
}
public void OnGoal(Team team){
if(!isServer){
Debug.LogWarning("OnGoal called on client, skipping");
return;}
RpcPlayGoalScoredSfx();
freezeInput=true;
@@ -311,6 +435,13 @@ public class GameManager : NetworkBehaviour
hitCounter = 0;
}
[ClientRpc]
void RpcPlayGoalScoredSfx()
{
if (AudioManager.instance != null)
AudioManager.instance.PlayGoalScoredSfxSequence();
}
[ClientRpc]
void RpcGameOver(Team team){
gameOver(team);
+8
View File
@@ -0,0 +1,8 @@
using UnityEngine;
public class IntroSceneManager : MonoBehaviour
{
public void OnPlay(){
LevelLoadManager.LoadLevel("MainMenu");
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: bdd03d8cc6ae1ad4d89c39ba1d752da7
+2
View File
@@ -124,6 +124,8 @@ public class NetPlayer : NetworkBehaviour
Vector2 direction = GameManager.SelectedPuck.lineEnd;
CmdOnPointerUp(direction);
CameraEffects.instance.ReleaseStretchFactor();
}
[Command]
+23
View File
@@ -65,6 +65,13 @@ public class Puck : NetworkBehaviour
float clamp = GameManager.instance.puckDragClampMax;
lineEnd = Vector2.ClampMagnitude(lineEnd, clamp);
if (NetPlayer.localPlayer != null
&& team == NetPlayer.localPlayer.myTeam
&& GameManager.instance.SelectedTeam == team)
{
CameraEffects.instance.SetStretchFactor(lineEnd.magnitude / clamp);
}
// Only two points for the line
lineRenderer.positionCount = 2;
lineRenderer.SetPosition(0, Vector3.zero);
@@ -111,6 +118,22 @@ public class Puck : NetworkBehaviour
}
void OnCollisionEnter2D(Collision2D collision)
{
if (!collision.collider.CompareTag("Puck"))
return;
// Both pucks get this callback; play once per contact.
if (gameObject.GetInstanceID() >= collision.gameObject.GetInstanceID())
return;
float otherSpeed = collision.relativeVelocity.magnitude;
Debug.Log("Puck collision speed: " + otherSpeed);
float maxVolSpeed =5f;
float vol = Mathf.Clamp(otherSpeed / maxVolSpeed,0.1f,1);
if (AudioManager.instance != null)
AudioManager.instance.PlayPuckHit(vol);
}
public void Reset(Vector3? position = null, float duration = 0.5f)
{
Vector3 pos = position ?? startPosition;
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 37e196db53cb2f948969d90e648a355a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 07c0cc0c5a337f24986822f356e2f9f2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,38 @@
using UnityEngine;
[CreateAssetMenu(fileName = "AudioDirectory", menuName = "Scriptable Objects/AudioDirectory")]
public class AudioDirectory : ScriptableObject
{
[Header("Scenes")]
public string introSceneName = "Intro";
public string menuSceneName = "MainMenu";
public string gameSceneName = "Game";
[Header("Music")]
public AudioClip introMusic;
public AudioClip menuMusic;
public AudioClip gameMusic;
[Header("SFX")]
[Header("Ball")]
public AudioClip[] ballHits;
public AudioClip[] puckHits;
public AudioClip[] wallHits;
public AudioClip[] ballHitNet;
[Header("Game")]
public AudioClip[] timerBeep;
public AudioClip[] matchMakingBeep;
public AudioClip[] matchFound;
[Header("Referee")]
public AudioClip[] refereeGoal;
public AudioClip[] refereeWhistle;
[Header("Crowd")]
public AudioClip[] crowdAmbientNoise;
public AudioClip[] crowdAmbientNoiseNearGoal;
public AudioClip[] crowdCheering;
public AudioClip[] crowdNoiseMatchStart;
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 776cfba92ccdba54d8129b1338fbcc6c
+524
View File
@@ -0,0 +1,524 @@
using System.Collections;
using DG.Tweening;
using UnityEngine;
using UnityEngine.SceneManagement;
public class AudioManager : MonoBehaviour
{
[Header("Sources")]
public AudioSource musicSource;
public AudioSource uiSfxSource;
public AudioSource gameSfxSource;
public AudioSource crowdSfxSourceA;
public AudioSource crowdSfxSourceB;
[Header("Music")]
public AudioDirectory audioDirectory;
[SerializeField] float musicFadeDuration = 1f;
[Header("Crowd bed")]
[SerializeField] float crowdFadeDuration = 1f;
[SerializeField] float maxCrowdVolume = 1f;
public static AudioManager instance;
float _maxMusicVolume;
bool _inGame;
CrowdNoiseType _currentCrowdNoiseType;
bool _crowdPrimaryIsA = true;
bool _crowdBedInitialized;
Coroutine _introRoutine;
Coroutine _goalSfxSequenceRoutine;
void Awake()
{
if (instance != null)
{
Destroy(gameObject);
return;
}
instance = this;
DontDestroyOnLoad(gameObject);
_maxMusicVolume = musicSource != null ? musicSource.volume : 1f;
}
void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
void Start()
{
var scene = SceneManager.GetActiveScene();
if (scene.IsValid())
ApplyMusicForScene(scene.name);
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (!scene.IsValid())
return;
ApplyMusicForScene(scene.name);
}
void ApplyMusicForScene(string sceneName)
{
if (audioDirectory == null)
return;
bool comingFromGame = _inGame;
if (sceneName == audioDirectory.gameSceneName)
{
_inGame = true;
EnableCrowdSourcesForGame();
SetCrowdNoiseType(CrowdNoiseType.GameStart);
if (musicSource != null)
FadeOutMusic();
return;
}
_inGame = false;
FadeOutAndDisableCrowdSources();
if (musicSource == null)
return;
if (sceneName == audioDirectory.menuSceneName)
{
if (comingFromGame)
{
StopIntroRoutine();
FadeInMenuMusic();
}
else
HandleMenuSceneMusicWhileIntroMayStillPlay();
}
else if (sceneName == audioDirectory.introSceneName)
{
StartIntroMusic();
}
}
void StartIntroMusic()
{
if (audioDirectory.introMusic == null)
{
EnsureMenuMusic();
return;
}
if (musicSource.clip == audioDirectory.introMusic && musicSource.isPlaying)
return;
StopIntroRoutine();
DOTween.Kill(musicSource);
musicSource.Stop();
musicSource.clip = audioDirectory.introMusic;
musicSource.loop = false;
musicSource.volume = _maxMusicVolume;
musicSource.Play();
_introRoutine = StartCoroutine(IntroThenMenuWhenDone());
}
IEnumerator IntroThenMenuWhenDone()
{
yield return new WaitWhile(() => musicSource != null && musicSource.isPlaying && musicSource.clip == audioDirectory.introMusic);
_introRoutine = null;
if (musicSource == null || instance == null)
yield break;
if (SceneManager.GetActiveScene().name == audioDirectory.gameSceneName)
yield break;
PlayMenuTrack(_maxMusicVolume);
}
void HandleMenuSceneMusicWhileIntroMayStillPlay()
{
if (IsIntroStillPlaying())
{
if (_introRoutine == null)
_introRoutine = StartCoroutine(IntroThenMenuWhenDone());
return;
}
if (!IsMenuMusicActiveAtFullVolume())
EnsureMenuMusic();
}
bool IsIntroStillPlaying()
{
return audioDirectory.introMusic != null && musicSource.clip == audioDirectory.introMusic && musicSource.isPlaying;
}
bool IsMenuMusicActiveAtFullVolume()
{
return audioDirectory.menuMusic != null && musicSource.clip == audioDirectory.menuMusic && musicSource.isPlaying
&& Mathf.Approximately(musicSource.volume, _maxMusicVolume);
}
void EnsureMenuMusic()
{
if (audioDirectory.menuMusic == null)
return;
DOTween.Kill(musicSource);
if (musicSource.clip == audioDirectory.menuMusic && musicSource.isPlaying && Mathf.Approximately(musicSource.volume, _maxMusicVolume))
return;
PlayMenuTrack(_maxMusicVolume);
}
void PlayMenuTrack(float volume)
{
if (audioDirectory.menuMusic == null)
return;
musicSource.Stop();
musicSource.clip = audioDirectory.menuMusic;
musicSource.loop = true;
musicSource.volume = volume;
musicSource.Play();
}
void FadeOutMusic()
{
StopIntroRoutine();
DOTween.Kill(musicSource);
musicSource.DOFade(0f, musicFadeDuration);
}
void FadeInMenuMusic()
{
if (audioDirectory.menuMusic == null)
return;
StopIntroRoutine();
DOTween.Kill(musicSource);
musicSource.Stop();
musicSource.clip = audioDirectory.menuMusic;
musicSource.loop = true;
musicSource.volume = 0f;
musicSource.Play();
musicSource.DOFade(_maxMusicVolume, musicFadeDuration);
}
void StopIntroRoutine()
{
if (_introRoutine != null)
{
StopCoroutine(_introRoutine);
_introRoutine = null;
}
}
#region SFX
public void PlayWallHit(float vol=1){
gameSfxSource.PlayOneShot(audioDirectory.wallHits[Random.Range(0, audioDirectory.wallHits.Length)], vol);
}
public void PlayBallHit(float vol=1){
if (audioDirectory.ballHits != null && audioDirectory.ballHits.Length > 0)
gameSfxSource.PlayOneShot(audioDirectory.ballHits[Random.Range(0, audioDirectory.ballHits.Length)],vol);
}
public void PlayPuckHit(float vol=1){
if (audioDirectory.puckHits != null && audioDirectory.puckHits.Length > 0)
gameSfxSource.PlayOneShot(audioDirectory.puckHits[Random.Range(0, audioDirectory.puckHits.Length)],vol);
}
public void PlayBallHitNet(){
if (audioDirectory.ballHitNet != null && audioDirectory.ballHitNet.Length > 0)
gameSfxSource.PlayOneShot(audioDirectory.ballHitNet[Random.Range(0, audioDirectory.ballHitNet.Length)]);
}
public void PlayGoalScoredSfxSequence()
{
if (gameSfxSource == null || audioDirectory == null)
return;
if (_goalSfxSequenceRoutine != null)
StopCoroutine(_goalSfxSequenceRoutine);
_goalSfxSequenceRoutine = StartCoroutine(GoalScoredSfxSequenceRoutine());
}
IEnumerator GoalScoredSfxSequenceRoutine()
{
CrowdNoiseType typeBefore = _currentCrowdNoiseType;
AudioManager.instance.SetCrowdNoiseType(CrowdNoiseType.Cheer);
AudioClip net = PickRandomClip(audioDirectory.ballHitNet);
if (net != null)
{
gameSfxSource.PlayOneShot(net);
yield return new WaitForSeconds(net.length);
}
AudioClip whistle = PickRandomClip(audioDirectory.refereeWhistle);
if (whistle != null)
{
gameSfxSource.PlayOneShot(whistle);
yield return new WaitForSeconds(whistle.length);
}
AudioClip goal = PickRandomClip(audioDirectory.refereeGoal);
if (goal != null)
{
gameSfxSource.PlayOneShot(goal);
yield return new WaitForSeconds(goal.length);
}
_goalSfxSequenceRoutine = null;
AudioManager.instance.SetCrowdNoiseType(typeBefore);
}
static AudioClip PickRandomClip(AudioClip[] clips)
{
if (clips == null || clips.Length == 0)
return null;
return clips[Random.Range(0, clips.Length)];
}
public void PlayTimerBeep(){
if (audioDirectory.timerBeep != null && audioDirectory.timerBeep.Length > 0)
uiSfxSource.PlayOneShot(audioDirectory.timerBeep[Random.Range(0, audioDirectory.timerBeep.Length)]);
}
public void PlayMatchMakingBeep(){
if (audioDirectory.matchMakingBeep != null && audioDirectory.matchMakingBeep.Length > 0)
uiSfxSource.PlayOneShot(audioDirectory.matchMakingBeep[Random.Range(0, audioDirectory.matchMakingBeep.Length)]);
}
public void PlayMatchFound(){
if (audioDirectory.matchFound != null && audioDirectory.matchFound.Length > 0)
uiSfxSource.PlayOneShot(audioDirectory.matchFound[Random.Range(0, audioDirectory.matchFound.Length)]);
}
public void PlayRefereeGoal(){
if (audioDirectory.refereeGoal != null && audioDirectory.refereeGoal.Length > 0)
gameSfxSource.PlayOneShot(audioDirectory.refereeGoal[Random.Range(0, audioDirectory.refereeGoal.Length)]);
}
public void PlayRefereeWhistle(){
if (audioDirectory.refereeWhistle != null && audioDirectory.refereeWhistle.Length > 0)
gameSfxSource.PlayOneShot(audioDirectory.refereeWhistle[Random.Range(0, audioDirectory.refereeWhistle.Length)]);
}
public void PlayCrowdAmbientNoise(){
if (audioDirectory.crowdAmbientNoise != null && audioDirectory.crowdAmbientNoise.Length > 0)
gameSfxSource.PlayOneShot(audioDirectory.crowdAmbientNoise[Random.Range(0, audioDirectory.crowdAmbientNoise.Length)]);
}
public void PlayCrowdAmbientNoiseNearGoal(){
if (audioDirectory.crowdAmbientNoiseNearGoal != null && audioDirectory.crowdAmbientNoiseNearGoal.Length > 0)
gameSfxSource.PlayOneShot(audioDirectory.crowdAmbientNoiseNearGoal[Random.Range(0, audioDirectory.crowdAmbientNoiseNearGoal.Length)]);
}
public void PlayCrowdCheering(){
if (audioDirectory.crowdCheering != null && audioDirectory.crowdCheering.Length > 0)
gameSfxSource.PlayOneShot(audioDirectory.crowdCheering[Random.Range(0, audioDirectory.crowdCheering.Length)]);
}
public void PlayCrowdNoiseMatchStart(){
if (audioDirectory.crowdNoiseMatchStart != null && audioDirectory.crowdNoiseMatchStart.Length > 0)
gameSfxSource.PlayOneShot(audioDirectory.crowdNoiseMatchStart[Random.Range(0, audioDirectory.crowdNoiseMatchStart.Length)]);
}
public void SetIsBallNearGoal(bool nearGoal)
{
if (!_inGame)
return;
if (_currentCrowdNoiseType == CrowdNoiseType.Cheer || _currentCrowdNoiseType == CrowdNoiseType.GameStart)
return;
SetCrowdNoiseType(nearGoal ? CrowdNoiseType.NearGoal : CrowdNoiseType.Normal);
}
public void SetCrowdNoiseType(CrowdNoiseType type) => SetCrowdNoiseType(type, crowdFadeDuration);
public void SetCrowdNoiseType(CrowdNoiseType type, float fadeDuration)
{
if (audioDirectory == null || crowdSfxSourceA == null || crowdSfxSourceB == null)
return;
if (_crowdBedInitialized && _currentCrowdNoiseType == type)
return;
float dur = fadeDuration >= 0f ? fadeDuration : crowdFadeDuration;
AudioClip[] clips = GetCrowdClipsForType(audioDirectory, type);
if (clips == null || clips.Length == 0)
{
FadeOutCrowdBed(dur);
_currentCrowdNoiseType = type;
_crowdBedInitialized = true;
return;
}
AudioClip clip = clips[Random.Range(0, clips.Length)];
if (clip == null)
{
FadeOutCrowdBed(dur);
_currentCrowdNoiseType = type;
_crowdBedInitialized = true;
return;
}
AudioSource outgoing = _crowdPrimaryIsA ? crowdSfxSourceA : crowdSfxSourceB;
AudioSource incoming = _crowdPrimaryIsA ? crowdSfxSourceB : crowdSfxSourceA;
DOTween.Kill(outgoing);
DOTween.Kill(incoming);
incoming.clip = clip;
incoming.loop = true;
incoming.volume = 0f;
incoming.Play();
outgoing.DOFade(0f, dur).OnComplete(() =>
{
outgoing.Stop();
outgoing.clip = null;
});
incoming.DOFade(maxCrowdVolume, dur);
_crowdPrimaryIsA = !_crowdPrimaryIsA;
_currentCrowdNoiseType = type;
_crowdBedInitialized = true;
}
static AudioClip[] GetCrowdClipsForType(AudioDirectory dir, CrowdNoiseType type)
{
if (dir == null)
return null;
switch (type)
{
case CrowdNoiseType.GameStart:
return dir.crowdNoiseMatchStart;
case CrowdNoiseType.Normal:
return dir.crowdAmbientNoise;
case CrowdNoiseType.NearGoal:
return dir.crowdAmbientNoiseNearGoal;
case CrowdNoiseType.Cheer:
return dir.crowdCheering;
default:
return null;
}
}
void EnableCrowdSourcesForGame()
{
if (crowdSfxSourceA != null)
crowdSfxSourceA.enabled = true;
if (crowdSfxSourceB != null)
crowdSfxSourceB.enabled = true;
}
void FadeOutAndDisableCrowdSources()
{
DOTween.Kill(crowdSfxSourceA);
DOTween.Kill(crowdSfxSourceB);
int pending = 0;
if (crowdSfxSourceA != null)
pending++;
if (crowdSfxSourceB != null)
pending++;
if (pending == 0)
return;
void FinishOne()
{
pending--;
if (pending > 0)
return;
if (crowdSfxSourceA != null)
crowdSfxSourceA.enabled = false;
if (crowdSfxSourceB != null)
crowdSfxSourceB.enabled = false;
_crowdBedInitialized = false;
_crowdPrimaryIsA = true;
}
FadeCrowdSourceOutOrImmediate(crowdSfxSourceA, crowdFadeDuration, FinishOne);
FadeCrowdSourceOutOrImmediate(crowdSfxSourceB, crowdFadeDuration, FinishOne);
}
void FadeOutCrowdBed(float dur)
{
DOTween.Kill(crowdSfxSourceA);
DOTween.Kill(crowdSfxSourceB);
FadeCrowdSourceOut(crowdSfxSourceA, dur);
FadeCrowdSourceOut(crowdSfxSourceB, dur);
_crowdPrimaryIsA = true;
}
static void FadeCrowdSourceOutOrImmediate(AudioSource source, float dur, System.Action onComplete)
{
if (source == null)
{
onComplete?.Invoke();
return;
}
if (!source.enabled || (!source.isPlaying && Mathf.Approximately(source.volume, 0f)))
{
source.Stop();
source.clip = null;
onComplete?.Invoke();
return;
}
source.DOFade(0f, dur).OnComplete(() =>
{
source.Stop();
source.clip = null;
onComplete?.Invoke();
});
}
static void FadeCrowdSourceOut(AudioSource source, float dur)
{
if (source == null)
return;
if (!source.isPlaying)
{
source.clip = null;
return;
}
source.DOFade(0f, dur).OnComplete(() =>
{
source.Stop();
source.clip = null;
});
}
#endregion
}
public enum CrowdNoiseType{
GameStart,
Normal,
NearGoal,
Cheer
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6aae5977db663834f86b46979365fa92
+12
View File
@@ -0,0 +1,12 @@
using UnityEngine;
public class RotateAround : MonoBehaviour
{
public Vector3 axis = Vector3.up;
public float speed = 10f;
public Vector3 center = Vector3.zero;
void Update()
{
transform.RotateAround(transform.position + center, axis, speed * Time.deltaTime);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f67c475e52308cd42a56f95fd38c86c4
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0b498645b8402b742a93101fc04df79f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,61 @@
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
using UnityEngine.SceneManagement;
using System.Collections;
public class LevelLoadManager : MonoBehaviour
{
public static LevelLoadManager instance;
public Image contentImage;
public float transitionDuration = 0.5f;
CanvasGroup canvasGroup;
public bool isShowing => canvasGroup.alpha == 1;
void Awake()
{
if(instance != null){
Destroy(gameObject);
return;
}
canvasGroup = GetComponent<CanvasGroup>();
instance = this;
DontDestroyOnLoad(gameObject);
Hide();
}
public static void LoadLevel(string levelName){
instance.loadLevel(levelName);
}
void loadLevel(string levelName){
StartCoroutine(CoroutineLoadLevel(levelName));
}
IEnumerator CoroutineLoadLevel(string levelName){
instance.Show();
yield return new WaitForSeconds(transitionDuration);
yield return SceneManager.LoadSceneAsync(levelName);
instance.Hide();
}
public void Show(){
canvasGroup.blocksRaycasts=true;
canvasGroup.interactable=true;
contentImage.fillOrigin = 0;
canvasGroup.DOFade(1, transitionDuration).SetEase(Ease.OutSine);
contentImage.DOFillAmount(1, transitionDuration).SetEase(Ease.OutSine);
}
public void Hide(){
canvasGroup.blocksRaycasts=false;
canvasGroup.interactable=false;
contentImage.fillOrigin = 1;
canvasGroup.DOFade(0, transitionDuration).SetEase(Ease.InSine);
contentImage.DOFillAmount(0, transitionDuration).SetEase(Ease.InSine);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: be7470bea6c16b9439ddf2a399e94cfc
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3dd42b9e0f78cdb4eb43c211cc4097c3
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,31 @@
using UnityEngine;
public class CanvasGroupUtils : MonoBehaviour
{
public UnityEngine.UI.Graphic[] graphics;
public bool useOverrideColor = false;
public Color overrideColor = Color.white;
void OnValidate()
{
RefreshColor();
}
void Update()
{
RefreshColor();
}
void RefreshColor(){
if(useOverrideColor)
{
foreach(var graphic in graphics)
{
graphic.color = new Color(overrideColor.r, overrideColor.g, overrideColor.b, overrideColor.a);
}
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c6e9b80351cd150478194c9959e87012
+22
View File
@@ -0,0 +1,22 @@
using UnityEngine;
using DG.Tweening;
using UnityEngine.UI;
[RequireComponent(typeof(Image))]
public class ImageBlinker : MonoBehaviour
{
public float duration = 0.5f;
public Ease ease = Ease.InOutSine;
public float from = 0f;
public float to = 1f;
public int loops = -1;
public LoopType loopType = LoopType.Yoyo;
void Start()
{
var image = GetComponent<Image>();
var c = image.color;
c.a = from;
image.color = c;
image.DOFade(to, duration).SetEase(ease).SetLoops(loops, loopType);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ee65e1f8cf52cc24b989d032d572c1fa
+34
View File
@@ -0,0 +1,34 @@
using UnityEngine;
using DG.Tweening;
using UnityEngine.EventSystems;
[RequireComponent(typeof(EventTrigger))]
public class ScaleOnHover : MonoBehaviour
{
public float scaleFactor = 1.1f;
public float duration = 0.1f;
public Ease ease = Ease.OutBack;
void Start()
{
EventTrigger eventTrigger = GetComponent<EventTrigger>();
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerEnter;
entry.callback.AddListener((data) => { OnPointerEnter((PointerEventData)data); });
eventTrigger.triggers.Add(entry);
entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerExit;
entry.callback.AddListener((data) => { OnPointerExit((PointerEventData)data); });
eventTrigger.triggers.Add(entry);
}
public void OnPointerEnter(PointerEventData eventData)
{
transform.DOScale(scaleFactor, duration).SetEase(ease);
}
public void OnPointerExit(PointerEventData eventData)
{
transform.DOKill();
transform.DOScale(1f, duration).SetEase(ease);
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 4e4c65221cd965e45853c892a9facd82