我這裏用到了Qframeworke插件。
如果不用的話你可以直接刪掉相關的代碼就可以了。
廢話不多說,先上代碼!
附上資源鏈接:我是想免費分享的,但是那個什麼積分是自動的,我沒法設置多少積分
https://download.csdn.net/download/qq_42489774/11890690
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using QFramework;
using QF.Res;
/// <summary>
/// 存儲路徑的父物體
/// </summary>
public class Mspaint : MonoBehaviour
{
[SerializeField]
private int state = 0;
//畫筆顏色
private Color paintColor = Color.red;
[HideInInspector]
//畫筆大小
private float paintSize = 0.05f;
//LineRenderer 組件
private LineRenderer curretnLine;
//畫筆材質
public Material lineMaterial;
//存儲畫線節點
private List<Vector3> positions = new List<Vector3>();
private bool isMouseDown = false;
//記錄上一次節點位置
private Vector3 lastMousePosition = Vector3.zero;
//圓圈的半徑
public Slider slider;
public GameObject CanvasX;
//裝line盒子
public Transform ChildrenBox;
//是否可以執行畫畫
bool IsPaint = true;
//劃線,直線/圓圈等等模式
private int Line_Mode = 0;
public Dropdown dropdown;
//圓圈
Vector3 v; //起點,Vector2是2D,當然也可以換Vector3
Vector3 origin;
float R; //半徑
int positionCount; //完成一個圓的總點數,
float angle; //轉角,三個點形成的兩段線之間的夾角
Quaternion q; //Quaternion四元數
//圓圈
public bool IsCircle = false;
public bool IsLine = false;
[SerializeField]
public RawImage RayImage;
private Texture2D Pen;
//private Sprite goods;
ResLoader loader = new ResLoader();
private void Awake()
{
//Value可以不用傳過去,因爲這個值可以從item中獲取;
slider.onValueChanged.AddListener((float value) => slider.transform.GetChild(0).GetComponent<Text>().text=value.ToString());
dropdown.onValueChanged.AddListener((int value) => Line_Mode = value);
Pen = loader.LoadSync<Texture2D>("Pen");
// goods = Sprite.Create(Pen, new Rect(0, 0, Pen.width, Pen.height), new Vector2(0.5f, 0.5f));
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.F3))
{
IsPaint = !IsPaint;
ChildrenBox.gameObject.SetActive(!IsPaint);
CanvasX.gameObject.SetActive(!IsPaint);
RayImage.gameObject.SetActive(!IsPaint);
if (!IsPaint)
{
Cursor.SetCursor(Pen, new Vector2(0f,50f),CursorMode.ForceSoftware);
}
else
{
Cursor.SetCursor(null,new Vector2(0.5f,0.5f),CursorMode.ForceSoftware);
}
}
if (Input.GetKeyUp(KeyCode.Escape))
{
IsPaint = true;//禁止繪畫
ChildrenBox.gameObject.SetActive(false);
CanvasX.gameObject.SetActive(false);
}
if (!IsPaint)
{
//撤銷功能
if (Input.GetKeyDown(KeyCode.F2))
{
if (state > 0)
{
Destroy(ChildrenBox.Find("Line_" + state).gameObject);
state--;
}
}
if (Input.GetMouseButtonDown(0) && Line_Mode == 0)//自由畫線
{
IsLine = false;
state++;
//新建一個空物體
GameObject go = new GameObject("Line_" + state);
go.transform.SetParent(ChildrenBox);
//給空物體添加LineRenderer組件
curretnLine = go.AddComponent<LineRenderer>();
//設置材質
curretnLine.material = lineMaterial;
//畫筆大小
curretnLine.startWidth = paintSize;
curretnLine.endWidth = paintSize;
//畫筆顏色
curretnLine.startColor = paintColor;
curretnLine.endColor = paintColor;
//畫筆圓滑度
curretnLine.numCornerVertices = 5;
curretnLine.numCapVertices = 5;
//返回射線和平面交點位置
Vector3 position = GetMousePoint();
//添加畫線路勁節點(Vector3)
AddPosition(position);
isMouseDown = true;
}
else if (Input.GetMouseButtonDown(0) && Line_Mode == 1)//
{
IsLine = false;
state++;
//新建一個空物體
GameObject go = new GameObject("Line_" + state);
go.transform.SetParent(ChildrenBox);
//給空物體添加LineRenderer組件
curretnLine = go.AddComponent<LineRenderer>();
//設置材質
curretnLine.material = lineMaterial;
//畫筆大小
curretnLine.startWidth = paintSize;
curretnLine.endWidth = paintSize;
//畫筆顏色
curretnLine.startColor = paintColor;
curretnLine.endColor = paintColor;
//畫筆圓滑度
curretnLine.numCornerVertices = 5;
curretnLine.numCapVertices = 5;
v = GetMousePoint();
// R = 6;
positionCount = 180;
angle = 360f / (positionCount - 1);
//curretnLine = curretnLine.GetComponent<LineRenderer>();
curretnLine.positionCount = positionCount;
curretnLine.SetPosition(0, v);
curretnLine.SetPosition(1, v);
IsCircle = true;
}
if (IsCircle&& Line_Mode == 1)
{
curretnLine.SetPosition(1, GetMousePoint());
R = Vector3.Distance(v, GetMousePoint())/2;
origin = (v + GetMousePoint()) / 2;
Debug.Log(R);
DrawCircle2();
}
if (Input.GetMouseButtonUp(0) && Line_Mode == 1)
{
positionCount = 180;
curretnLine.SetPosition(0, v);
curretnLine.SetPosition(1, GetMousePoint());
origin =( v + GetMousePoint())/2;
IsCircle = false;
DrawCircle();
//isMouseDown = true;
//Vector3 position = GetMousePoint();
//////添加畫線路勁節點(Vector3)
//AddPosition(position);
}
if (Input.GetMouseButtonDown(0) && Line_Mode == 2)
{
state++;
//新建一個空物體
GameObject go = new GameObject("Line_" + state);
go.transform.SetParent(ChildrenBox);
//給空物體添加LineRenderer組件
curretnLine = go.AddComponent<LineRenderer>();
//設置材質
curretnLine.material = lineMaterial;
//畫筆大小
curretnLine.startWidth = paintSize;
curretnLine.endWidth = paintSize;
//畫筆顏色
curretnLine.startColor = paintColor;
curretnLine.endColor = paintColor;
//畫筆圓滑度
curretnLine.numCornerVertices = 5;
curretnLine.numCapVertices = 5;
curretnLine.positionCount = 2;//設置兩點
Vector3 position = GetMousePoint();
//設置指示線的起點和終點
IsLine = true;
curretnLine.SetPosition(0, position);
}
if (IsLine&&Line_Mode == 2)
{
curretnLine.SetPosition(1, GetMousePoint());
}
if (Input.GetMouseButtonUp(0) && Line_Mode == 2)
{
curretnLine.positionCount = 2;//設置兩點
IsLine = false;
Vector3 position = GetMousePoint();
curretnLine.SetPosition(1, position);
}
void DrawCircle()
{
if (Line_Mode == 1)
{
positionCount = 180;
}
else if (Line_Mode == 2)
{
positionCount = 2;
}
for (int i = 0; i < positionCount; i++)
{
if (i != 0)
{
q = Quaternion.Euler(q.eulerAngles.x, q.eulerAngles.y, q.eulerAngles.z + angle);
}
if (Line_Mode == 1)
{
Vector3 forwardPosition = (Vector3)origin + q * Vector3.down * R;//slider.value*10;
curretnLine.SetPosition(i, forwardPosition);
}
else if (Line_Mode == 2)
{
positionCount = 2;
Vector3 forwardPosition = (Vector3)origin + q * Vector3.down * R;//slider.value*10;
curretnLine.SetPosition(i, forwardPosition);
}
}
}
void DrawCircle2()
{
if (Line_Mode == 1)
{
positionCount = 180;
}
else if (Line_Mode == 2)
{
positionCount = 2;
}
for (int i = 0; i < positionCount; i++)
{
if (i != 0)
{
q = Quaternion.Euler(q.eulerAngles.x, q.eulerAngles.y, q.eulerAngles.z + angle);
}
Vector3 forwardPosition = (Vector3)origin + q * Vector3.down * R;//slider.value*10;
curretnLine.SetPosition(i, forwardPosition);
}
}
//記錄鼠標滑過的路勁節點
if (isMouseDown)
{
//返回射線和平面交點位置
Vector3 position = GetMousePoint();
if (Vector3.Distance(position, lastMousePosition) > 0.1f)
{
//添加畫線路徑節點(Vector3)
AddPosition(position);
}
}
//鼠標擡起時
if (Input.GetMouseButtonUp(0))
{
curretnLine = null;
//清空上一次的畫線節點 list
positions.Clear();
isMouseDown = false;
}
}
}
//添加畫線路勁節點(Vector3)
void AddPosition(Vector3 position)
{
//讓畫線前置畫布0.1距離防止部分畫線不顯示
position.z -= 0.1f;
positions.Add(position);
//
curretnLine.positionCount = positions.Count;
curretnLine.SetPositions(positions.ToArray());
lastMousePosition = position;
}
//返回射線和平面交點位置
Vector3 GetMousePoint()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
bool isCollider = Physics.Raycast(ray, out hit);
if (isCollider)
{
//返回射線和平面交點位置
return hit.point;
}
return Vector3.zero;
}
#region
//畫布上的toggle按鈕事件
//切換爲紅色
public void OnRedColorChanged(bool isOn)
{
if (isOn)
{
paintColor = Color.red;
}
}
//切換爲黃色
public void OnYellowColorChanged(bool isOn)
{
if (isOn)
{
paintColor = Color.yellow;
}
}
//切換爲白色
public void OnWhiteColorChanged(bool isOn)
{
if (isOn)
{
paintColor = Color.white;
}
}
//切換爲黑色
public void OnBlackColorChanged(bool isOn)
{
if (isOn)
{
paintColor = Color.black;
}
}
//設置畫線粗細 0.1
public void OnPoint1Changed(bool isOn)
{
if (isOn)
{
paintSize = 0.05f;
}
}
//設置畫線粗細 0.2
public void OnPoint2Changed(bool isOn)
{
if (isOn)
{
paintSize = 0.1f;
}
}
//設置畫線粗細 0.4
public void OnPoint4Changed(bool isOn)
{
if (isOn)
{
paintSize = 0.2f;
}
}
//清空畫布
public void OnClearPanelButton()
{
state = 0;
if (transform.childCount > 0)
{
int lineCount = ChildrenBox.childCount;
for (int i = 0; i < ChildrenBox.childCount; i++)
{
Destroy(ChildrenBox.GetChild(i).gameObject);
}
}
}
#endregion
}