ai unity3d

2017-05-27 11:29:19 qq_27880427 阅读数 2472
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

 正如你所见,这是一个非常简单的脚本,它有一个Length属性,如果发起请求,就可以返回航点数组的长度和大小。GetPoint方法返回数组中指定下标位置的特定航点的位置。

 然后,Unity调用OnDrawGizmos方法,以在编辑器环境中绘制出组件,在游戏视图中,如果不打开gizmos,那么这些绘图是不会渲染的。

public class Path : MonoBehaviour {

    public bool bDebug = true;
    public float Radius = 2.0f;
    public Vector3[] pointA;

    public float Length
    {
        get
        {
            return pointA.Length;
        }
    }

    public Vector3 GetPoint(int index)
    {
        return pointA[index];
    }

    private void OnDrawGizmos()
    {
        if (!bDebug)
        {
            return;
        }
        for (int i = 0; i < pointA.Length; i++)
        {
            if (i + 1< pointA.Length)
            {
                Debug.DrawLine(pointA[i], pointA[i + 1], Color.red);
            }
        }
    }
}
接下来,我们有了车辆实体,在本例中它只是一个简单的立方体对象,创建完脚本后,我们将添加VehicleFollowing脚本组件。该脚本接受几个参数,首先是它需要跟随的路径的引用对象,其次是在正确计算它的加速度时需要用到的速度(Speed)属性和质量(Mass)属性。选中是否循环(IsLooping)这个标志,会让实体一直沿着路径循环行进。
 public Path path;
    public float speed = 20.0f;
    public float mass = 5.0f;
    public bool isLooping = true;
    private float curSpeed;
    private int curPathIndex;
    private float pathLength;
    private Vector3 targetPoint;

    Vector3 velocity;

    private void Start()
    {
        pathLength = path.Length;
        curPathIndex = 0;
        velocity = transform.forward;
    }

    private void Update()
    {

        curSpeed = speed * Time.deltaTime;

        targetPoint = path.GetPoint(curPathIndex);
        if (Vector3.Distance(transform.position,targetPoint)<path.Radius)
        {
            if (curPathIndex < pathLength - 1)
            {
                curPathIndex++;
            }
            else if (isLooping)
            {
                curPathIndex = 0;
            }
            else
            {
                return;
            }
        }
        if (curPathIndex >= pathLength)
        {
            return;
        }

        if (curPathIndex >= pathLength -1 && !isLooping)
        {
            velocity += Steer(targetPoint,true);
        }else
        {
            velocity += Steer(targetPoint);
        }

        transform.position += velocity;
        transform.rotation = Quaternion.LookRotation(velocity);
    }
 首先我们对属性进行初始化,并在Start方法中将我们的velocity向量设置为向前的方向。在Update方法中,我们通过计算实体的当前位置和与特定航点的距离是否在其半径范围内,来判断它是否已经到达了特定的航点。如果它在范围内,我们只需将下表递增,来找到数组中的下一个航点,如果已经是最后一个航点,我们就需要检查IsLooping标签是否已设置,如果已经设置,我们就将目标设为起始点,否则,我们只需停止在那个点即可。不过,我们也可以让对象转过来,沿着它过来的路线原路返回。

在接下来,我们将在Steer方法中计算加速度,然后旋转我们的实体,并根据速度和方向相应的更新它的位置。Steer方法接收参数,需要移动到Vector3类型的目标位置,无论这个点是否是在最终的航点。我们需要做的第一件事就是计算当前位置与目标位置的剩余距离。用目标位置向量减去当前位置的向量,得出向目标位置移动的向量。 这个向量的模就是剩余的距离。我们然后将这个向量规格化以保持其方向属性。现在,如果这是最后一个航点,并且距离小于我们刚刚决定使用的数字10,我们就随着距离越来越近逐渐降低速度,直到速度最终降为零。否则,我们就以刚刚的速度值更新目标速度。通过从目标速度向量中减去当前速度向量,我们可以计算出新的引导向量。然后用这个向量除以实体的质量,就得出了加速度。

    public Vector3 Steer(Vector3 target,bool bFinalPoint = false)
    {
        Vector3 desiredVelocity = target - transform.position;
        float dist = desiredVelocity.magnitude;

        desiredVelocity.Normalize();
        if (bFinalPoint && dist < 10.0f)
        {
            desiredVelocity *= (curSpeed * (dist / 10.0f));
        }
        Vector3 steeringForce = desiredVelocity - velocity;
        Vector3 acceleration = steeringForce / mass;
        return acceleration;
    }


2017-08-30 17:07:20 sun1018974080 阅读数 5005
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

        首先你应该搞清楚的一点AI脚本属于一个工具类脚本,工具类脚本的含义就是他应当是由策划人员来绑定游戏对象使用的。也就是说AI脚本程序员应当写的非常的灵活,策划人员可以通过修改脚本对外的变量数值接口就能控制其中的敌人AI。接着创建一个c#脚本AI.CS ,如下图所示,目前脚本对外留出枚举接口变量,策划人员在使用这条脚本时选择对应敌人类型即可。(注:这里仅仅是示例,细致的话还可以将很多敌人详细的信息写入,如:攻击速度、技能类型、移动速度、命中率、攻击百分比、等等,但是一定要让你的脚本写的比较灵活,策划人员在外面选择即可完成)因为目前是一个示例,所以我在这里只简单的区分的敌人类型。

 

Unity3D研究院之游戏开发中的人工智能AI(三十八) - 雨松MOMO程序研究院 - 1

 

下面时这段简单AI的脚本

AI.CS

 

 

如下图所示,我们在游戏世界中添加两个敌人,此时给敌人们都绑定上AI的脚本,编辑器中设置不同的敌人类型,敌人执行各自的生命周期,当你控制主角与接近敌人时,敌人开始追击你并且向你展开攻击。

 

Unity3D研究院之游戏开发中的人工智能AI(三十八) - 雨松MOMO程序研究院 - 2

 

         demo仅仅是一个示例,主要希望大家明白一个道理。在编写Unity游戏脚本时,一定要想想这条脚本和对象的生命周期,切记每一条脚本只管和自己有关的东西,和自己无关的东西一概不要管。不然你会发现你的脚本会越写越乱,下一篇文章我会写点我平时在Unity3D开发中时如何搭建架构的,希望大家多多讨论,互相学习。

下载地址:http://vdisk.weibo.com/s/hmJUs

2016-12-16 14:38:55 mango9126 阅读数 1600
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

人工智能这个东西在游戏中是非常重要的,人工智能说简单了就是根据随机的数字让敌人执行一些动作或逻辑,说难了TA需要一个非常复杂的算法,本文我主要说说Unity3D中人工智能的脚本如何来编写。

        首先你应该搞清楚的一点AI脚本属于一个工具类脚本,工具类脚本的含义就是他应当是由策划人员来绑定游戏对象使用的。也就是说AI脚本程序员应当写的非常的灵活,策划人员可以通过修改脚本对外的变量数值接口就能控制其中的敌人AI。接着创建一个c#脚本AI.CS ,如下图所示,目前脚本对外留出枚举接口变量,策划人员在使用这条脚本时选择对应敌人类型即可。(注:这里仅仅是示例,细致的话还可以将很多敌人详细的信息写入,如:攻击速度、技能类型、移动速度、命中率、攻击百分比、等等,但是一定要让你的脚本写的比较灵活,策划人员在外面选择即可完成)因为目前是一个示例,所以我在这里只简单的区分的敌人类型。

 

Unity3D研究院之游戏开发中的人工智能AI(三十八) - 雨松MOMO程序研究院 - 1

 

下面时这段简单AI的脚本

AI.CS

 

 

如下图所示,我们在游戏世界中添加两个敌人,此时给敌人们都绑定上AI的脚本,编辑器中设置不同的敌人类型,敌人执行各自的生命周期,当你控制主角与接近敌人时,敌人开始追击你并且向你展开攻击。

 

Unity3D研究院之游戏开发中的人工智能AI(三十八) - 雨松MOMO程序研究院 - 2

 

         demo仅仅是一个示例,主要希望大家明白一个道理。在编写Unity游戏脚本时,一定要想想这条脚本和对象的生命周期,切记每一条脚本只管和自己有关的东西,和自己无关的东西一概不要管。不然你会发现你的脚本会越写越乱,下一篇文章我会写点我平时在Unity3D开发中时如何搭建架构的,希望大家多多讨论,互相学习。

下载地址:http://vdisk.weibo.com/s/hmJUs

2019-09-22 14:05:19 fengliaoai 阅读数 14639
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

每周更新unity3d视频教程,从入门到就业,官方unity3d培训,上千门实时更新课程,供学员在线观看学习,unity3d游戏开发,可以让学员随时随地学习!
免费网上学习unity3d自学教程,国内名师机构专业授课,O基础快速学习,1小时快速入门,7天unity3d自学教程学习,能力快速提升,优质作品随手呈现!

unity3d菜鸟自学教程介绍

unity3d难学吗?

unity3d自学教程目录

unity3d视频教程百度网盘下载

unity3d难学吗?
学习unity3d特效,多来学习路线网看教程,一线游戏特效老师,游戏特效就业安排!学习unity3d特效入门+进阶+精通选择专业才能学得专业!

unity3d自学教程目录
课程介绍:
Unity3d史诗 MMO ARPG 课程《泰斗破坏神》,精心设计将包含200+课时,由视频课时+直播课时+测试课时混合组成。最重头unity3d ARGP课程,完整的 ARPG 网络游戏开发教学。包含多人合作,在线多人游戏开发,角色创建系统,作战系统,RPG系统,技能系统,任务系统,商店系统。

课程大纲:

单机版功能实现

项目概要
登录系统
角色创建、选择、自定义系统
场景加载与游戏存储记录
角色控制
聊天通讯
游戏AI
战斗系统
游戏角色与玩家信息系统
商店系统
道具系统
装备系统
装备与道具掉落
仓库与背包系统
副本系统
任务系统
地图与寻路系统

网络版功能实现

服务端搭建
登录系统
角色选择
游戏场景
聊天功能
角色具体信息
商店系统
道具系统
装备系统
仓库和背包
副本系统
任务系统

unity3d视频教程百度网盘下载
http://www.xuexiluxian.net/unity3d-cainiao-zixue.html

2017-10-24 19:50:11 m0_37283423 阅读数 10558
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

最近在研究神经网络+遗传算法在Unity给NPC用(一个可以学习训练的NPC是不是很酷)
说一下神经网络真的不复杂,多看一看是能理解的;如果有不对的地方欢迎指出批评。立马修改以免误人;
神经网络定义的东西我就浅表的谈一谈:
   计算机的人工神经网络简单分为三层:输入层、隐藏层、输出层;
   这三个层的用意用形象的实例描述一下:
      输入层就代表人的感官;
      隐藏层(其实也是多了一层输出变成了下一组的输入)大脑中的神经元;
      输出层用来接收处理后的信息进行分类反应;
   简单的说输入和输出两层连,中间过程执行一个公式:
[url=][/url]加权
   [url=][/url]进行激活函数(f())
假设
输入:一局王者荣耀里
1、  你看见对面5人调戏大龙:
2、  其中3人残血;
3、  自身满血;
隐藏层:
1也就是输出层 就是下一层的输入层;
隐藏层就是再分类再判断比如队友距离、队友血量、队友支援、敌方支援再和上一次的输出进行处理;(一般情况下一层就够了)
最后输出层:
1、  如果判断过去: 你将会操作人物移动靠近
2、  如果判断不过去:你将操作人物离开;
这么讲应该能理解这三个层的用意把;神经网络这个词我就不解释了 麻烦,想当初我看的时候废话一大堆,然后我并没看明白;
其实人的行为就是受到神经的刺激而产生的;在我的理解中权重就是这个人的情绪偏向;
[url=][/url]
一张图看一下:
   其实人工的神经网络很难真正实现生物神经网络;
看一下输入层的 图例中输入值为(1、0、1、1);权重就是这个参数影响判断的绝对能力:取决主观意向;
假设第一层的权重为(0.3、-0.5、0.9、1);
根据激励函数求出(不加偏移)=0.3+0+0.9+1=2.2D  有人会问 这个2.2D有什么作用;这个是这个激励函数对于输入函数和每个输入函数在神经中的重要性来得出的;在输出函数中需要一个阈值来判断这些值需要执行的动作;可能大于2.2D需要执行一系列动作;
看图讲什么原理什么都太虚;我直接贴代码讲解代码实现 (毕竟我是一个连复制粘贴都嫌麻烦的人)
神经网络铺建:
using System;
using System.Collections.Generic;


    public class NeNetwork {
        public double[][][] _NetWeights;
        public int[] _Layers;
        public double[][] _Offset;
        public double[][] _Outputs;
        public NeurFunction[][] Functions;

        public NeNetwork(params int[] Layers) {//(5,3)  5输入  3输出
            
            var layersLength = Layers.Length;
            this._Layers = Layers;//各层数量={5,3}

            _Outputs = new double[layersLength][];//输出={[5个],[3个]}
           
            for (var i = 0; i < layersLength; i++) {
                _Outputs[i] = new double[this._Layers[i]];
            }
             Functions = new NeurFunction[layersLength - 1][];//方法={[5个]}
            _NetWeights = new double[layersLength - 1][][];//权重={[[3个][3个][3个][3个][3个]]}
            _Offset = new double[layersLength - 1][];//偏移={[3个]}

            var func = new SiFunction();
            for (var i = 0; i < layersLength - 1; i++) {
                _NetWeights[i] = new double[this._Layers[i]][];
                Functions[i] = new NeurFunction[this._Layers[i]];
                for (var j = 0; j < this._Layers[i]; j++) {
                    _NetWeights[i][j] = new double[this._Layers[i + 1]];
                    Functions[i][j] = func;
                }
                _Offset[i] = new double[this._Layers[i + 1]];
            }
        }

        public void SetFunction(int layerIndex, NeurFunction func) {
            for (var j = 0; j < _Layers[layerIndex + 1]; j++) {
                Functions[layerIndex][j] = func;
            }
        }

        public double[] GetOut(double[] inputs) {
            
            for (var i = 0; i < _Layers[0]; i++) {
                _Outputs[0][i] = inputs[i];
            }
            var qqsout = new double[_Layers[_Layers.Length - 1]];
            for (var i = 1; i < _Layers.Length; i++) { 
                for (var j = 0; j < _Layers[i]; j++) {// 3 
                    double before = 0;    
                    for (var k = 0; k < _Layers[i - 1]; k++) { // 5
                        before += _Outputs[i - 1][k] * _NetWeights[i - 1][k][j];//权重这个J
                    }
                    before += _Offset[i - 1][j];
                    _Outputs[i][j] = Functions[i - 1][j].Compute(before);//把三个输出层的结果发送到输出层方便调用
                }
            }
            qqsout = _Outputs[_Layers.Length - 1];
            return qqsout;

        }

        public List<double> GetWeightsList() {
            var qws = new List<double>();
            for (var i = 0; i < _Layers.Length - 1; i++) {
                qws.AddRange(_Offset[i]);
            }
            for (var i = 0; i < _Layers.Length - 1; i++) {
                for (var j = 0; j < _Layers[i]; j++) {
                    qws.AddRange(_NetWeights[i][j]);
                }
            }
            return qws;
        }
        
        public void UpdateWeights(List<double> data) {
            var id = 0;
            for (var i = 0; i < _Layers.Length - 1; i++) {
                for (var j = 0; j < _Layers[i + 1]; j++) {
                    _Offset[i][j] = data[id];
                    id++;
                }
               }

            for (var i = 0; i < _Layers.Length - 1; i++) {
                for (var j = 0; j < _Layers[i]; j++) {
                    for (var k = 0; k < _Layers[i + 1]; k++) {
                        _NetWeights[i][j][k] = data[id];
                        id++;
                    }
                }
            }
        }

        //瞎JB写了
        public double[] ShowTimes() {  //反向传播权重更新
            List<double> currentList = new List<double>();
            for (int i = 0; i < _Layers[0]; i++)
            {
                currentList.Add(_Outputs[0][i]);
            }
             double a=  -(_Outputs[0][1] - 0.5f) * _Outputs[0][1] * (1 - _Outputs[0][1]);  //-(输出-样本)*输出*(1-输出);  反向传播加权
           double  b= 1 / 1 - Math.Exp(-_Outputs[0][1]);   //非线性阶段函数
            double c = Math.Tanh(_Outputs[0][1]);     //切函数
            return currentList.ToArray();  //返回更新权重  然后数值更新 *学习率

        }

  }
    

输出处理类+接口:
using System;


	public interface NeurFunction {
		double Compute(double x);
	}
	
	public class SiFunction : NeurFunction
    {
		public double Compute(double x) {
			return  1.0 / (1.0 + Math.Exp(-x)); //非线性激活函数
		}
	}
public class ThFunction : NeurFunction
{
    public double Compute(double x)
    {
        return x > 0.0 ? 1.0 : -1.0;
    }
}





如有不懂欢迎指正;后续我会好好整理一下再把遗传算法结合的探讨一下