Merge branch 'main' of https://scove-vault.duckdns.org/scove/HALLUCINATION
This commit is contained in:
8
Assets/Scripts/AI NPC.meta
Normal file
8
Assets/Scripts/AI NPC.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 92ace9da10dc8bd49a47cbdb18f8d052
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
44
Assets/Scripts/AI NPC/BehavourTreeCore.cs
Normal file
44
Assets/Scripts/AI NPC/BehavourTreeCore.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public enum NodeState
|
||||
{
|
||||
Success, Failure, Running
|
||||
}
|
||||
|
||||
public abstract class Node
|
||||
{
|
||||
protected NodeState state;
|
||||
public NodeState State => state;
|
||||
public abstract NodeState Evaluate();
|
||||
}
|
||||
|
||||
public class Selector : Node
|
||||
{
|
||||
protected List<Node> nodes = new List<Node>(); // children nodes
|
||||
|
||||
public Selector(List<Node> nodes)
|
||||
{
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
public override NodeState Evaluate()
|
||||
{
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
switch (node.Evaluate())
|
||||
{
|
||||
case NodeState.Failure:
|
||||
continue;
|
||||
case NodeState.Success:
|
||||
state = NodeState.Success;
|
||||
return state;
|
||||
case NodeState.Running:
|
||||
state = NodeState.Running;
|
||||
return state;
|
||||
}
|
||||
}
|
||||
state = NodeState.Failure;
|
||||
return state;
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/AI NPC/BehavourTreeCore.cs.meta
Normal file
2
Assets/Scripts/AI NPC/BehavourTreeCore.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05bb68bbe2862134ab45f5267ec4b6bb
|
||||
73
Assets/Scripts/AI NPC/EnemyAI.cs
Normal file
73
Assets/Scripts/AI NPC/EnemyAI.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class EnemyAI : MonoBehaviour
|
||||
{
|
||||
public Transform player;
|
||||
public float detectRange = 10f;
|
||||
public float moveSpeed = 3f;
|
||||
public float rotateSpeed = 50f;
|
||||
public bool isAttackReady;
|
||||
|
||||
public Node behaviorTreeRoot;
|
||||
|
||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||
void Start()
|
||||
{
|
||||
InitBehaviorTree();
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (behaviorTreeRoot != null)
|
||||
{
|
||||
behaviorTreeRoot.Evaluate();
|
||||
}
|
||||
}
|
||||
|
||||
void InitBehaviorTree()
|
||||
{
|
||||
var chaseSequence = new Sequence(new List<Node>
|
||||
{
|
||||
new TaskNode(CheckCanSeePlayer),
|
||||
new TaskNode(ActionMoveToPlayer)
|
||||
});
|
||||
var rotationScanNode = new TaskNode(ActionRotationScan);
|
||||
behaviorTreeRoot = new Selector(new List<Node>
|
||||
{
|
||||
chaseSequence,
|
||||
rotationScanNode
|
||||
});
|
||||
}
|
||||
|
||||
private NodeState ActionRotationScan()
|
||||
{
|
||||
Debug.Log("ActionRotationScan");
|
||||
transform.Rotate(Vector3.up, rotateSpeed * Time.deltaTime);
|
||||
return NodeState.Running;
|
||||
}
|
||||
|
||||
private NodeState ActionMoveToPlayer()
|
||||
{
|
||||
Debug.Log($"Moving to Player");
|
||||
Vector3 dir = (player.position - transform.position).normalized;
|
||||
transform.position += dir * moveSpeed * Time.deltaTime;
|
||||
return NodeState.Running;
|
||||
}
|
||||
|
||||
private NodeState CheckCanSeePlayer()
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return NodeState.Failure;
|
||||
}
|
||||
float distance = Vector3.Distance(transform.position,player.position);
|
||||
if (distance < detectRange)
|
||||
{
|
||||
Debug.Log($"Player detected!");
|
||||
return NodeState.Success;
|
||||
}
|
||||
return NodeState.Failure;
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/AI NPC/EnemyAI.cs.meta
Normal file
2
Assets/Scripts/AI NPC/EnemyAI.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2224c27a7e8678e4a85f6604ba5e669a
|
||||
82
Assets/Scripts/AI NPC/GerminiNPC.cs
Normal file
82
Assets/Scripts/AI NPC/GerminiNPC.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
[Serializable]
|
||||
public class Part
|
||||
{
|
||||
public string text;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Content
|
||||
{
|
||||
public Part[] parts;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Candidate
|
||||
{
|
||||
public Content content;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class GeminiResponse
|
||||
{
|
||||
public Candidate[] candidates;
|
||||
}
|
||||
public class GerminiNPC :MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private string apiKey = "AQ.Ab8RN6I2hU_p8yHiPNNHtWzYBiLugbPP22gC6lzTWaYEWj4v0g";
|
||||
[SerializeField]
|
||||
private string germiniURL =
|
||||
"https://generativelanguage.googleapis.com/v1beta/models/gemini-flash-latest:generateContent";
|
||||
|
||||
public string npcPersona =
|
||||
$"Nguơi là ột thợ lão thợ rèn cọc cằn tên là TOm,ngươi rất ghét những kẻ mang phế liệu đến tiệm của mình.Ch trả lời ngắn gọn trong 2 câu,theo phong cách trung cổ";
|
||||
|
||||
public string playerHeldItem = "Thanh kiếm rỉ sét";
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Keyboard.current.spaceKey.wasPressedThisFrame)
|
||||
{
|
||||
StartCoroutine(GetGerminiReponse());
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator GetGerminiReponse()
|
||||
{
|
||||
var jsonBody = $@"{{""systemInstruction"": {{""parts"": [{{ ""text"": ""{npcPersona}"" }}]}},
|
||||
""contents"": [{{""parts"": [{{ ""text"": ""Ta muốn bán cho ông món đồ này cho ông {playerHeldItem}""}}]}}] }} ";
|
||||
var requestURL = $"{germiniURL}?ket={apiKey}";
|
||||
using (var request = new UnityWebRequest(germiniURL, "POST"))
|
||||
{
|
||||
var bodyRaw = Encoding.UTF8.GetBytes(jsonBody);
|
||||
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
|
||||
request.downloadHandler = new DownloadHandlerBuffer();
|
||||
request.SetRequestHeader("Content-Type", "application/json");
|
||||
yield return request.SendWebRequest();
|
||||
if (request.result == UnityWebRequest.Result.ProtocolError)
|
||||
{
|
||||
Debug.LogError(request.error);
|
||||
}
|
||||
else
|
||||
{
|
||||
var responseTEXT = request.downloadHandler.text;
|
||||
var germiniResponse=JsonUtility.FromJson<GeminiResponse>(responseTEXT);
|
||||
if (germiniResponse.candidates.Length > 0)
|
||||
{
|
||||
var npcResponse = germiniResponse.candidates[0].content.parts[0].text;
|
||||
Debug.Log(npcResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
Assets/Scripts/AI NPC/GerminiNPC.cs.meta
Normal file
2
Assets/Scripts/AI NPC/GerminiNPC.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4efda4e7a7dcac84ca938e2264ed0276
|
||||
47
Assets/Scripts/AI NPC/Sequence.cs
Normal file
47
Assets/Scripts/AI NPC/Sequence.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class Sequence : Node
|
||||
{
|
||||
private List<Node> nodes = new List<Node>();
|
||||
|
||||
public Sequence(List<Node> nodes)
|
||||
{
|
||||
this.nodes = nodes;
|
||||
}
|
||||
|
||||
public override NodeState Evaluate()
|
||||
{
|
||||
var isAnyChildRunning = false;
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
switch (node.Evaluate())
|
||||
{
|
||||
case NodeState.Failure:
|
||||
state = NodeState.Failure;
|
||||
return state;
|
||||
case NodeState.Success:
|
||||
continue;
|
||||
case NodeState.Running:
|
||||
isAnyChildRunning = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
state = isAnyChildRunning ? NodeState.Running : NodeState.Success;
|
||||
return state;
|
||||
}
|
||||
}
|
||||
public class TaskNode : Node
|
||||
{
|
||||
public delegate NodeState TaskDelegate();
|
||||
private TaskDelegate action;
|
||||
|
||||
public TaskNode(TaskDelegate action)
|
||||
{
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public override NodeState Evaluate()
|
||||
{
|
||||
return action();
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/AI NPC/Sequence.cs.meta
Normal file
2
Assets/Scripts/AI NPC/Sequence.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bfbdb66c26ddee84199051308b223b09
|
||||
@@ -347,13 +347,7 @@ namespace Hallucinate.UI
|
||||
particle.style.opacity = 0f;
|
||||
particle.style.scale = Vector3.one;
|
||||
|
||||
Sequence.Create()
|
||||
.Group(Tween.Custom(0f, 0.6f, duration: 0.05f, onValueChange: val => particle.style.opacity = val))
|
||||
.Chain(Tween.Custom(0.6f, 0f, duration: 0.35f, onValueChange: val => particle.style.opacity = val))
|
||||
.Group(Tween.Custom(1f, 0.2f, duration: 0.4f, onValueChange: val => {
|
||||
particle.style.scale = new StyleScale(new Scale(new Vector3(val, val, 1f)));
|
||||
}))
|
||||
.OnComplete(() => particle.style.display = DisplayStyle.None);
|
||||
|
||||
}
|
||||
|
||||
private float GetCurrentScale() => (_uiDocument != null && _uiDocument.panelSettings != null) ? _uiDocument.panelSettings.scale : 1.0f;
|
||||
|
||||
Reference in New Issue
Block a user