192 lines
5.4 KiB
C#
192 lines
5.4 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class ChalkDrawer : MonoBehaviour
|
|
{
|
|
[SerializeField] private Camera _camera;
|
|
[SerializeField] private RenderTexture _boardTexture;
|
|
[SerializeField] private float _brushSize = 0.02f;
|
|
[SerializeField] private float _eraserSize = 0.05f;
|
|
[SerializeField] private Color _chalkColor = Color.white;
|
|
[SerializeField] private float _holdDistance = 1.5f;
|
|
[SerializeField] private float _followSpeed = 12f;
|
|
|
|
public bool IsHoldingChalk => _holdingChalk;
|
|
|
|
private bool _holdingChalk = false;
|
|
private bool _isErasing = false;
|
|
private GameObject _chalkObject = null;
|
|
private Rigidbody _chalkRb = null;
|
|
private Collider _chalkCollider = null;
|
|
private Texture2D _drawTexture;
|
|
private bool _textureReady = false;
|
|
private Vector3 _originalPosition;
|
|
|
|
private void Start()
|
|
{
|
|
InitTexture();
|
|
}
|
|
|
|
private void InitTexture()
|
|
{
|
|
if (_boardTexture == null) return;
|
|
|
|
_drawTexture = new Texture2D(_boardTexture.width, _boardTexture.height, TextureFormat.RGBA32, false);
|
|
|
|
Color[] pixels = new Color[_boardTexture.width * _boardTexture.height];
|
|
for (int i = 0; i < pixels.Length; i++)
|
|
pixels[i] = Color.black;
|
|
_drawTexture.SetPixels(pixels);
|
|
_drawTexture.Apply();
|
|
|
|
Graphics.Blit(_drawTexture, _boardTexture);
|
|
|
|
GameObject board = GameObject.FindGameObjectWithTag("Board");
|
|
if (board != null)
|
|
{
|
|
MeshRenderer boardRenderer = board.GetComponent<MeshRenderer>();
|
|
if (boardRenderer != null)
|
|
boardRenderer.material.mainTexture = _boardTexture;
|
|
}
|
|
|
|
_textureReady = true;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!_holdingChalk) return;
|
|
|
|
HandleHolding();
|
|
HandleDrawing();
|
|
|
|
if (Input.GetMouseButtonDown(1))
|
|
DropChalk();
|
|
}
|
|
|
|
public void PickupChalk(GameObject chalk)
|
|
{
|
|
_originalPosition = chalk.transform.position;
|
|
_chalkObject = chalk;
|
|
_chalkRb = chalk.GetComponent<Rigidbody>();
|
|
_chalkCollider = chalk.GetComponent<Collider>();
|
|
|
|
if (_chalkRb != null)
|
|
{
|
|
_chalkRb.useGravity = false;
|
|
_chalkRb.velocity = Vector3.zero;
|
|
_chalkRb.angularVelocity = Vector3.zero;
|
|
}
|
|
|
|
if (_chalkCollider != null)
|
|
_chalkCollider.enabled = false;
|
|
|
|
_isErasing = false;
|
|
_holdingChalk = true;
|
|
}
|
|
|
|
public void PickupTowel(GameObject towel)
|
|
{
|
|
_originalPosition = towel.transform.position;
|
|
_chalkObject = towel;
|
|
_chalkRb = towel.GetComponent<Rigidbody>();
|
|
_chalkCollider = towel.GetComponent<Collider>();
|
|
|
|
if (_chalkRb != null)
|
|
{
|
|
_chalkRb.useGravity = false;
|
|
_chalkRb.velocity = Vector3.zero;
|
|
_chalkRb.angularVelocity = Vector3.zero;
|
|
}
|
|
|
|
if (_chalkCollider != null)
|
|
_chalkCollider.enabled = false;
|
|
|
|
_isErasing = true;
|
|
_holdingChalk = true;
|
|
}
|
|
|
|
private void HandleHolding()
|
|
{
|
|
if (_chalkObject == null) return;
|
|
|
|
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
|
|
Vector3 targetPos = ray.origin + ray.direction * _holdDistance;
|
|
|
|
_chalkObject.transform.position = Vector3.Lerp(
|
|
_chalkObject.transform.position,
|
|
targetPos,
|
|
Time.deltaTime * _followSpeed
|
|
);
|
|
}
|
|
|
|
private void HandleDrawing()
|
|
{
|
|
if (!_textureReady) return;
|
|
|
|
if (Input.GetMouseButton(0))
|
|
{
|
|
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
|
|
if (Physics.Raycast(ray, out RaycastHit hit))
|
|
{
|
|
if (hit.collider.CompareTag("Board"))
|
|
DrawOnTexture(hit.textureCoord);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawOnTexture(Vector2 uv)
|
|
{
|
|
Color paintColor = _isErasing ? Color.black : _chalkColor;
|
|
float size = _isErasing ? _eraserSize : _brushSize;
|
|
|
|
int x = (int)(uv.x * _drawTexture.width);
|
|
int y = (int)(uv.y * _drawTexture.height);
|
|
int radius = Mathf.Max(1, (int)(size * _drawTexture.width));
|
|
|
|
for (int i = -radius; i <= radius; i++)
|
|
{
|
|
for (int j = -radius; j <= radius; j++)
|
|
{
|
|
if (i * i + j * j <= radius * radius)
|
|
{
|
|
int px = Mathf.Clamp(x + i, 0, _drawTexture.width - 1);
|
|
int py = Mathf.Clamp(y + j, 0, _drawTexture.height - 1);
|
|
_drawTexture.SetPixel(px, py, paintColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
_drawTexture.Apply();
|
|
Graphics.Blit(_drawTexture, _boardTexture);
|
|
}
|
|
|
|
private void DropChalk()
|
|
{
|
|
if (_chalkObject == null) return;
|
|
|
|
if (_chalkRb != null)
|
|
{
|
|
_chalkRb.useGravity = false;
|
|
_chalkRb.velocity = Vector3.zero;
|
|
_chalkRb.angularVelocity = Vector3.zero;
|
|
}
|
|
|
|
_chalkObject.transform.position = _originalPosition;
|
|
|
|
if (_chalkRb != null)
|
|
{
|
|
_chalkRb.useGravity = true;
|
|
_chalkRb.WakeUp();
|
|
}
|
|
|
|
if (_chalkCollider != null)
|
|
_chalkCollider.enabled = true;
|
|
|
|
_holdingChalk = false;
|
|
_isErasing = false;
|
|
_chalkObject = null;
|
|
_chalkRb = null;
|
|
_chalkCollider = null;
|
|
}
|
|
} |