158 lines
6.2 KiB
C#
158 lines
6.2 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using Cinemachine;
|
|
|
|
namespace CryingSnow.FarmingIsland
|
|
{
|
|
public class DairyAnimal : Animal
|
|
{
|
|
// Virtual cameras for different viewing angles during the milking minigame.
|
|
[SerializeField] private CinemachineVirtualCamera leftVirtualCamera;
|
|
[SerializeField] private CinemachineVirtualCamera rightVirtualCamera;
|
|
|
|
// Skinned mesh renderer representing the milk bucket that visually fills up during the minigame.
|
|
[SerializeField] private SkinnedMeshRenderer milkBucket;
|
|
|
|
// Sound effect played when milking.
|
|
[SerializeField] private AudioClip milkingSound;
|
|
|
|
private List<Teat> teats = new List<Teat>(); // List of teats involved in the minigame.
|
|
private float minTeatSwipeDistance; // Minimum swipe distance required to increase milking progress.
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
|
|
// Get all teats and initially deactivate them.
|
|
teats = GetComponentsInChildren<Teat>(true).ToList();
|
|
teats.ForEach(t => t.gameObject.SetActive(false));
|
|
|
|
// Deactivate the milk bucket at the start.
|
|
milkBucket.gameObject.SetActive(false);
|
|
|
|
// Set the minimum swipe distance based on screen height (30%).
|
|
minTeatSwipeDistance = Screen.height * 0.3f;
|
|
}
|
|
|
|
protected override IEnumerator MiniGame()
|
|
{
|
|
// Activate teats and reset their blend shapes.
|
|
teats.ForEach(t =>
|
|
{
|
|
t.gameObject.SetActive(true);
|
|
t.SetBlendShapes(0.1f);
|
|
});
|
|
|
|
// Activate and reset the milk bucket blend shape.
|
|
milkBucket.gameObject.SetActive(true);
|
|
milkBucket.SetBlendShapeWeight(0, 0f);
|
|
|
|
controller.InteruptMovement(); // Stop any animal movement during the minigame.
|
|
player.SetVisible(false); // Hide the player during the minigame.
|
|
|
|
// Activate the appropriate virtual camera based on the position.
|
|
var vCam = leftVirtualCamera.gameObject;
|
|
if (rightVirtualCamera.transform.position.z < leftVirtualCamera.transform.position.z)
|
|
vCam = rightVirtualCamera.gameObject;
|
|
|
|
vCam.SetActive(true);
|
|
|
|
// Display the UI prompt and hide the HUD during the minigame.
|
|
UIManager.Instance.ProgressBar.Toggle($"Milk the {gameObject.name.ToLower()}!");
|
|
UIManager.Instance.ToggleHUD(false);
|
|
|
|
yield return new WaitForSeconds(1f);
|
|
|
|
int milkedCount = 0;
|
|
|
|
// Loop through each teat until all are milked.
|
|
while (milkedCount < teats.Count)
|
|
{
|
|
float blend = 0.1f;
|
|
Vector2 startTouchPosition = Vector2.zero;
|
|
Vector2 currentTouchPosition = Vector2.zero;
|
|
bool isSwiping = false;
|
|
|
|
// Handle the milking input and adjust the blend shape for the current teat.
|
|
while (blend < 0.9f)
|
|
{
|
|
if (Input.GetMouseButtonDown(0))
|
|
{
|
|
startTouchPosition = Input.mousePosition;
|
|
isSwiping = true;
|
|
}
|
|
|
|
if (Input.GetMouseButton(0) && isSwiping)
|
|
{
|
|
currentTouchPosition = Input.mousePosition;
|
|
float swipeDistance = startTouchPosition.y - currentTouchPosition.y;
|
|
|
|
if (swipeDistance > 0)
|
|
{
|
|
float blendIncrease = swipeDistance / minTeatSwipeDistance;
|
|
blend = Mathf.Clamp(0.1f + blendIncrease, 0.1f, 0.9f);
|
|
}
|
|
}
|
|
|
|
if (!isSwiping || (Input.GetMouseButtonUp(0) && isSwiping))
|
|
{
|
|
blend = Mathf.MoveTowards(blend, 0.1f, Time.deltaTime);
|
|
if (Input.GetMouseButtonUp(0))
|
|
{
|
|
isSwiping = false;
|
|
}
|
|
}
|
|
|
|
teats[milkedCount].SetBlendShapes(blend);
|
|
yield return null;
|
|
}
|
|
|
|
// Play the milking particle effect and update the milk bucket.
|
|
var milkParticle = teats[milkedCount].MilkParticle;
|
|
if (milkParticle != null)
|
|
{
|
|
milkParticle.Play();
|
|
AudioManager.Instance.PlaySFX(milkingSound);
|
|
float duration = milkParticle.main.duration;
|
|
float elapsedTime = 0f;
|
|
float targetWeight = (milkedCount + 1f) / teats.Count * 100;
|
|
|
|
while (elapsedTime < duration)
|
|
{
|
|
elapsedTime += Time.deltaTime;
|
|
float currentWeight = milkBucket.GetBlendShapeWeight(0);
|
|
float newWeight = Mathf.Lerp(currentWeight, targetWeight, elapsedTime / duration);
|
|
milkBucket.SetBlendShapeWeight(0, newWeight);
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
milkedCount++;
|
|
|
|
// Update the progress bar based on the number of teats milked.
|
|
float milkingProgress = (float)milkedCount / teats.Count;
|
|
UIManager.Instance.ProgressBar.UpdateDisplay(milkingProgress);
|
|
yield return null;
|
|
}
|
|
|
|
yield return new WaitForSeconds(0.3f);
|
|
|
|
// Reset the UI and camera after the minigame ends.
|
|
UIManager.Instance.ProgressBar.Toggle("");
|
|
UIManager.Instance.ToggleHUD(true);
|
|
|
|
player.SetVisible(true); // Make the player visible again.
|
|
vCam.SetActive(false); // Deactivate the virtual camera.
|
|
teats.ForEach(t => t.gameObject.SetActive(false)); // Deactivate teats.
|
|
milkBucket.gameObject.SetActive(false); // Deactivate the milk bucket.
|
|
|
|
yield return new WaitForSeconds(1f);
|
|
|
|
// Decide the next action for the animal after the minigame.
|
|
controller.DecideNextAction();
|
|
}
|
|
}
|
|
}
|