国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Unity UGUI的PhysicsRayc可變化、可擴(kuò)展aster (物理射線檢測(cè))組件的介紹及使用

這篇具有很好參考價(jià)值的文章主要介紹了Unity UGUI的PhysicsRayc可變化、可擴(kuò)展aster (物理射線檢測(cè))組件的介紹及使用。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

最近工作中需要用到MongoDB的事務(wù)操作,因此參考了一些資料封裝了一個(gè)小的組件,提供基礎(chǔ)的CRUD Repository基類 和 UnitOfWork工作單元模式。今天,就來(lái)簡(jiǎn)單介紹一下這個(gè)小組件。

關(guān)于MongoDB的事務(wù)

MongoDB在4.2版本開始全面支持了多文檔事務(wù),至今已過了四年了,雖然我們可能沒有在項(xiàng)目中用MongoDB來(lái)替代傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)如MySQL/SQL Server,但是不能否認(rèn)MongoDB已經(jīng)在事務(wù)能力上愈發(fā)成熟了。

在MongoDB中,所謂的事務(wù)主要指的是多個(gè)文檔的事務(wù),其使用方式和傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)差不多。但我們需要注意的是:多文檔事務(wù)只能應(yīng)用在副本集 或 mongos 節(jié)點(diǎn)上。如果你只是一個(gè)單點(diǎn)的mongo實(shí)例,是無(wú)法進(jìn)行多文檔事務(wù)實(shí)踐的。

畫外音:如果你對(duì)MongoDB感興趣,不妨看看我的這個(gè)系列博客:《MongoDB入門到實(shí)踐學(xué)習(xí)之旅》

那么,如何快速進(jìn)行事務(wù)操作呢?

在Mongo Shell中進(jìn)行事務(wù)

下面演示了如何通過Mongo Shell來(lái)進(jìn)行一個(gè)多文檔操作的事務(wù)提交:

var session = db.getMongo().startSession();
session.startTransaction({readConcern: { level: 'majority' },writeConcern: { w: 'majority' }});

var coll1 = session.getDatabase('students').getCollection('teams');
coll1.update({name: 'yzw-football-team'}, {$set: {members: 20}});

var coll2 = session.getDatabase('students').getCollection('records');
coll1.update({name: 'Edison'}, {$set: {gender: 'Female'}});

// 成功提交事務(wù)
session.commitTransaction();

// 失敗事務(wù)回滾
session.abortTransaction();

在.NET應(yīng)用中進(jìn)行事務(wù)

下面展示了在.NET應(yīng)用中通過MongoDB Driver來(lái)進(jìn)行事務(wù)的示例:

using (var clientSession = mongoClient.StartSession())
{
    try
    {
        var contacts = clientSession.Client.GetDatabase("testDB").GetCollection<Contact>("contacts");
        contacts.ReplaceOne(contact => contact.Id == "1234455", contact);
        var books = clientSession.Client.GetDatabase("testDB").GetCollection<Book>("books");
        books.DeleteOne(book => book.Id == "1234455");

        clientSession.CommitTransaction();
    }
    catch (Exception ex)
    {
        // to do some logging
        clientSession.AbortTransaction();
    }
}

在大部分的實(shí)際應(yīng)用中,我們通常都習(xí)慣使用數(shù)據(jù)倉(cāng)儲(chǔ)(Repository)的模式來(lái)進(jìn)行CRUD,同時(shí)也習(xí)慣用工作單元(UnitOfWork)模式來(lái)進(jìn)行協(xié)調(diào)多個(gè)Repository進(jìn)行事務(wù)提交。那么,如何在自己的項(xiàng)目中實(shí)現(xiàn)這個(gè)呢?

參考了一些資料后,自己實(shí)現(xiàn)了一個(gè)基礎(chǔ)小組件,暫且叫它:EDT.MongoProxy吧,我們來(lái)看看它是如何實(shí)現(xiàn)的。

單例的MongoClient

基于MongoDB的最佳時(shí)間,對(duì)于MongoClient最好設(shè)置為單例注入,因?yàn)樵贛ongoDB.Driver中MongoClient已經(jīng)被設(shè)計(jì)為線程安全可以被多線程共享,這樣可還以避免反復(fù)實(shí)例化MongoClient帶來(lái)的開銷,避免在極端情況下的性能低下。

這里暫且設(shè)計(jì)一個(gè)MongoDbConnection類,用于包裹這個(gè)MongoClient,然后將其以單例模式注入IoC容器中。

public class MongoDbConnection : IMongoDbConnection
{
    public IMongoClient DatabaseClient { get; }
    public string DatabaseName { get; }

    public MongoDbConnection(MongoDatabaseConfigs configs, IConfiguration configuration)
    {
        DatabaseClient = new MongoClient(configs.GetMongoClientSettings(configuration));
        DatabaseName = configs.DatabaseName;
    }
}

其中,這個(gè)MongoDatabaseConfigs類主要是獲取appsettings中的配置,用以生成MongoClient的對(duì)應(yīng)Settings。

/** Config Example
"MongoDatabaseConfigs": {
  "Servers": "xxx01.edisontalk.net,xxx02.edisontalk.net,xxx03.edisontalk.net",
  "Port": 27017,
  "ReplicaSetName": "edt-replica",
  "DatabaseName": "EDT_Practices",
  "AuthDatabaseName": "admin",

  "ApplicationName": "Todo",
  "UserName": "service_testdev",
  "Password": "xxxxxxxxxxxxxxxxxxxxxxxx",
  "UseTLS": true,
  "AllowInsecureTLS": true,
  "SslCertificatePath": "/etc/pki/tls/certs/EDT_CA.cer",
  "UseEncryption": true
}
**/
public class MongoDatabaseConfigs
{
    private const string DEFAULT_AUTH_DB = "admin"; // Default AuthDB: admin

    public string Servers { get; set; }
    public int Port { get; set; } = 27017; // Default Port: 27017
    public string ReplicaSetName { get; set; }
    public string DatabaseName { get; set; }
    public string DefaultCollectionName { get; set; } = string.Empty;
    public string ApplicationName { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public string AuthDatabaseName { get; set; } = DEFAULT_AUTH_DB; // Default AuthDB: admin
    public string CustomProperties { get; set; } = string.Empty;
    public bool UseTLS { get; set; } = false;
    public bool AllowInsecureTLS { get; set; } = true;
    public string SslCertificatePath { get; set; } = string.Empty;
    public bool StoreCertificateInKeyStore { get; set; } = false;


    public MongoClientSettings GetMongoClientSettings(IConfiguration configuration = null)
    {
        if (string.IsNullOrWhiteSpace(Servers))
            throw new ArgumentNullException("Mongo Servers Configuration is Missing!");

        if (string.IsNullOrWhiteSpace(UserName) || string.IsNullOrWhiteSpace(Password))
            throw new ArgumentNullException("Mongo Account Configuration is Missing!");

        // Base Configuration
        MongoClientSettings settings = new MongoClientSettings
        {
            ApplicationName = ApplicationName,
            ReplicaSetName = ReplicaSetName
        };


        // Credential
        settings.Credential = MongoCredential.CreateCredential(AuthDatabaseName, UserName, Password);

        // Servers
        var mongoServers = Servers.Split(",", StringSplitOptions.RemoveEmptyEntries).ToList();
        if (mongoServers.Count == 1) // Standalone
        {
            settings.Server = new MongoServerAddress(mongoServers.First(), Port);
            settings.DirectConnection = true;
        }

        if (mongoServers.Count > 1) // Cluster
        {
            var mongoServerAddresses = new List<MongoServerAddress>();
            foreach (var mongoServer in mongoServers)
            {
                var mongoServerAddress = new MongoServerAddress(mongoServer, Port);
                mongoServerAddresses.Add(mongoServerAddress);
            }
            settings.Servers = mongoServerAddresses;
            settings.DirectConnection = false;
        }

        // SSL
        if (UseTLS)
        {
            settings.UseTls = true;
            settings.AllowInsecureTls = AllowInsecureTLS;
            if (string.IsNullOrWhiteSpace(SslCertificatePath))
                throw new ArgumentNullException("SslCertificatePath is Missing!");

            if (StoreCertificateInKeyStore)
            {
                var localTrustStore = new X509Store(StoreName.Root);
                var certificateCollection = new X509Certificate2Collection();
                certificateCollection.Import(SslCertificatePath);
                try
                {
                    localTrustStore.Open(OpenFlags.ReadWrite);
                    localTrustStore.AddRange(certificateCollection);
                }
                catch (Exception ex)
                {
                    throw;
                }
                finally
                {
                    localTrustStore.Close();
                }
            }

            var certs = new List<X509Certificate> { new X509Certificate2(SslCertificatePath) };
            settings.SslSettings = new SslSettings();
            settings.SslSettings.ClientCertificates = certs;
            settings.SslSettings.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls13;
        }

        return settings;
    }
}

核心部分:MongoDbContext

這里我們主要仿照DbContext的設(shè)計(jì),設(shè)計(jì)一個(gè)MongoDbContext,它從IoC容器中獲取到單例的MongoClient,封裝了事務(wù)的開啟和提交,簡(jiǎn)化了應(yīng)用代碼的編寫。

public class MongoDbContext : IMongoDbContext
{
    private readonly IMongoDatabase _database;
    private readonly IMongoClient _mongoClient;
    private readonly IList<Func<IClientSessionHandle, Task>> _commands
        = new List<Func<IClientSessionHandle, Task>>();

    public MongoDbContext(IMongoDbConnection dbClient)
    {
        _mongoClient = dbClient.DatabaseClient;
        _database = _mongoClient.GetDatabase(dbClient.DatabaseName);
    }

    public void AddCommand(Func<IClientSessionHandle, Task> func)
    {
        _commands.Add(func);
    }

    public async Task AddCommandAsync(Func<IClientSessionHandle, Task> func)
    {
        _commands.Add(func);
        await Task.CompletedTask;
    }

    /// <summary>
    /// NOTES: Only works in Cluster mode
    /// </summary>
    public int Commit(IClientSessionHandle session)
    {
        try
        {
            session.StartTransaction();

            foreach (var command in _commands)
            {
                command(session);
            }

            session.CommitTransaction();
            return _commands.Count;
        }
        catch (Exception ex)
        {
            session.AbortTransaction();
            return 0;
        }
        finally
        {
            _commands.Clear();
        }
    }

    /// <summary>
    /// NOTES: Only works in Cluster mode
    /// </summary>
    public async Task<int> CommitAsync(IClientSessionHandle session)
    {
        try
        {
            session.StartTransaction();

            foreach (var command in _commands)
            {
                await command(session);
            }

            await session.CommitTransactionAsync();
            return _commands.Count;
        }
        catch (Exception ex)
        {
            await session.AbortTransactionAsync();
            return 0;
        }
        finally
        {
            _commands.Clear();
        }
    }

    public IClientSessionHandle StartSession()
    {
        var session = _mongoClient.StartSession();
        return session;
    }

    public async Task<IClientSessionHandle> StartSessionAsync()
    {
        var session = await _mongoClient.StartSessionAsync();
        return session;
    }

    public IMongoCollection<T> GetCollection<T>(string name)
    {
        return _database.GetCollection<T>(name);
    }

    public void Dispose()
    {
        GC.SuppressFinalize(this);
    }
}

Unity UGUI的PhysicsRayc可變化、可擴(kuò)展aster (物理射線檢測(cè))組件的介紹及使用,numpy

數(shù)據(jù)倉(cāng)儲(chǔ):MongoRepositoryBase

在實(shí)際項(xiàng)目中,我們都希望有一個(gè)基礎(chǔ)的RepositoryBase類,將CRUD的方法都封裝了,我們實(shí)際中就只需要?jiǎng)?chuàng)建一個(gè)對(duì)應(yīng)的Repository集成這個(gè)RepositoryBase就行了,無(wú)需再重復(fù)編寫CRUD的方法。那么,也就有了這個(gè)MongoRepositoryBase類:

public class MongoRepositoryBase<TEntity> : IMongoRepositoryBase<TEntity>
        where TEntity : MongoEntityBase, new()
{
    protected readonly IMongoDbContext _dbContext;
    protected readonly IMongoCollection<TEntity> _dbSet;
    private readonly string _collectionName;
    private const string _keyField = "_id";

    public MongoRepositoryBase(IMongoDbContext mongoDbContext)
    {
        _dbContext = mongoDbContext;
        _collectionName = typeof(TEntity).GetAttributeValue((TableAttribute m) => m.Name)
            ?? typeof(TEntity).Name;
        if (string.IsNullOrWhiteSpace(_collectionName))
            throw new ArgumentNullException("Mongo DatabaseName can't be NULL! Please set the attribute Table in your entity class.");

        _dbSet = mongoDbContext.GetCollection<TEntity>(_collectionName);
    }

    #region Create Part

    public async Task AddAsync(TEntity entity, IClientSessionHandle session = null)
    {
        if (session == null)
            await _dbSet.InsertOneAsync(entity);
        else
            await _dbContext.AddCommandAsync(async (session) => await _dbSet.InsertOneAsync(entity));
    }

    public async Task AddManyAsync(IEnumerable<TEntity> entityList, IClientSessionHandle session = null)
    {
        if (session == null)
            await _dbSet.InsertManyAsync(entityList);
        else
            await _dbContext.AddCommandAsync(async (session) => await _dbSet.InsertManyAsync(entityList));
    }

    #endregion

    # region Delete Part

    public async Task DeleteAsync(string id, IClientSessionHandle session = null)
    {
        if (session == null)
            await _dbSet.DeleteOneAsync(Builders<TEntity>.Filter.Eq(_keyField, new ObjectId(id)));
        else
            await _dbContext.AddCommandAsync(async (session) => await _dbSet.DeleteOneAsync(Builders<TEntity>.Filter.Eq(_keyField, new ObjectId(id))));
    }

    public async Task DeleteAsync(Expression<Func<TEntity, bool>> expression, IClientSessionHandle session = null)
    {
        if (session == null)
            await _dbSet.DeleteOneAsync(expression);
        else
            await _dbContext.AddCommandAsync(async (session) => await _dbSet.DeleteOneAsync(expression));
    }

    public async Task<DeleteResult> DeleteManyAsync(FilterDefinition<TEntity> filter, IClientSessionHandle session = null)
    {
        if (session == null)
            return await _dbSet.DeleteManyAsync(filter);

        await _dbContext.AddCommandAsync(async (session) => await _dbSet.DeleteManyAsync(filter));
        return new DeleteResult.Acknowledged(10);
    }

    public async Task<DeleteResult> DeleteManyAsync(Expression<Func<TEntity, bool>> expression, IClientSessionHandle session = null)
    {
        if (session == null)
            return await _dbSet.DeleteManyAsync(expression);

        await _dbContext.AddCommandAsync(async (session) => await _dbSet.DeleteManyAsync(expression));
        return new DeleteResult.Acknowledged(10);
    }

    #endregion

    #region Update Part

    public async Task UpdateAsync(TEntity entity, IClientSessionHandle session = null)
    {
        if (session == null)
            await _dbSet.ReplaceOneAsync(item => item.Id == entity.Id, entity);
        else
            await _dbContext.AddCommandAsync(async (session) => await _dbSet.ReplaceOneAsync(item => item.Id == entity.Id, entity));
    }

    public async Task UpdateAsync(Expression<Func<TEntity, bool>> expression, Expression<Action<TEntity>> entity, IClientSessionHandle session = null)
    {
        var fieldList = new List<UpdateDefinition<TEntity>>();

        if (entity.Body is MemberInitExpression param)
        {
            foreach (var item in param.Bindings)
            {
                var propertyName = item.Member.Name;
                object propertyValue = null;

                if (item is not MemberAssignment memberAssignment) continue;

                if (memberAssignment.Expression.NodeType == ExpressionType.Constant)
                {
                    if (memberAssignment.Expression is ConstantExpression constantExpression)
                        propertyValue = constantExpression.Value;
                }
                else
                {
                    propertyValue = Expression.Lambda(memberAssignment.Expression, null).Compile().DynamicInvoke();
                }

                if (propertyName != _keyField)
                {
                    fieldList.Add(Builders<TEntity>.Update.Set(propertyName, propertyValue));
                }
            }
        }

        if (session == null)
            await _dbSet.UpdateOneAsync(expression, Builders<TEntity>.Update.Combine(fieldList));
        else
            await _dbContext.AddCommandAsync(async (session) => await _dbSet.UpdateOneAsync(expression, Builders<TEntity>.Update.Combine(fieldList)));
    }

    public async Task UpdateAsync(FilterDefinition<TEntity> filter, UpdateDefinition<TEntity> update, IClientSessionHandle session = null)
    {
        if (session == null)
            await _dbSet.UpdateOneAsync(filter, update);
        else
            await _dbContext.AddCommandAsync(async (session) => await _dbSet.UpdateOneAsync(filter, update));
    }

    public async Task UpdateManyAsync(Expression<Func<TEntity, bool>> expression, UpdateDefinition<TEntity> update, IClientSessionHandle session = null)
    {
        if (session == null)
            await _dbSet.UpdateManyAsync(expression, update);
        else
            await _dbContext.AddCommandAsync(async (session) => await _dbSet.UpdateManyAsync(expression, update));
    }

    public async Task<UpdateResult> UpdateManayAsync(Dictionary<string, string> dic, FilterDefinition<TEntity> filter, IClientSessionHandle session = null)
    {
        var t = new TEntity();
        // Fields to be updated
        var list = new List<UpdateDefinition<TEntity>>();
        foreach (var item in t.GetType().GetProperties())
        {
            if (!dic.ContainsKey(item.Name)) continue;
            var value = dic[item.Name];
            list.Add(Builders<TEntity>.Update.Set(item.Name, value));
        }
        var updatefilter = Builders<TEntity>.Update.Combine(list);

        if (session == null)
            return await _dbSet.UpdateManyAsync(filter, updatefilter);

        await _dbContext.AddCommandAsync(async (session) => await _dbSet.UpdateManyAsync(filter, updatefilter));
        return new UpdateResult.Acknowledged(10, 10, null);
    }

    #endregion

    #region Read Part

    public async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> expression, bool readFromPrimary = true)
    {
        var readPreference = GetReadPreference(readFromPrimary);
        var queryData = await _dbSet.WithReadPreference(readPreference)
             .Find(expression)
             .FirstOrDefaultAsync();
        return queryData;
    }

    public async Task<TEntity> GetAsync(string id, bool readFromPrimary = true)
    {
        var readPreference = GetReadPreference(readFromPrimary);
        var queryData = await _dbSet.WithReadPreference(readPreference).FindAsync(Builders<TEntity>.Filter.Eq(_keyField, new ObjectId(id)));
        return queryData.FirstOrDefault();
    }

    public async Task<IEnumerable<TEntity>> GetAllAsync(bool readFromPrimary = true)
    {
        var readPreference = GetReadPreference(readFromPrimary);
        var queryAllData = await _dbSet.WithReadPreference(readPreference).FindAsync(Builders<TEntity>.Filter.Empty);
        return queryAllData.ToList();
    }

    public async Task<long> CountAsync(Expression<Func<TEntity, bool>> expression, bool readFromPrimary = true)
    {
        var readPreference = GetReadPreference(readFromPrimary);
        return await _dbSet.WithReadPreference(readPreference).CountDocumentsAsync(expression);
    }

    public async Task<long> CountAsync(FilterDefinition<TEntity> filter, bool readFromPrimary = true)
    {
        var readPreference = GetReadPreference(readFromPrimary);
        return await _dbSet.WithReadPreference(readPreference).CountDocumentsAsync(filter);
    }

    public async Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate, bool readFromPrimary = true)
    {
        var readPreference = GetReadPreference(readFromPrimary);
        return await Task.FromResult(_dbSet.WithReadPreference(readPreference).AsQueryable().Any(predicate));
    }

    public async Task<List<TEntity>> FindListAsync(FilterDefinition<TEntity> filter, string[]? field = null, SortDefinition<TEntity>? sort = null, bool readFromPrimary = true)
    {
        var readPreference = GetReadPreference(readFromPrimary);
        if (field == null || field.Length == 0)
        {
            if (sort == null)
                return await _dbSet.WithReadPreference(readPreference).Find(filter).ToListAsync();

            return await _dbSet.WithReadPreference(readPreference).Find(filter).Sort(sort).ToListAsync();
        }

        var fieldList = new List<ProjectionDefinition<TEntity>>();
        for (int i = 0; i < field.Length; i++)
        {
            fieldList.Add(Builders<TEntity>.Projection.Include(field[i].ToString()));
        }
        var projection = Builders<TEntity>.Projection.Combine(fieldList);
        fieldList?.Clear();

        if (sort == null)
            return await _dbSet.WithReadPreference(readPreference).Find(filter).Project<TEntity>(projection).ToListAsync();

        return await _dbSet.WithReadPreference(readPreference).Find(filter).Sort(sort).Project<TEntity>(projection).ToListAsync();
    }

    public async Task<List<TEntity>> FindListByPageAsync(FilterDefinition<TEntity> filter, int pageIndex, int pageSize, string[]? field = null, SortDefinition<TEntity>? sort = null, bool readFromPrimary = true)
    {
        var readPreference = GetReadPreference(readFromPrimary);
        if (field == null || field.Length == 0)
        {
            if (sort == null)
                return await _dbSet.WithReadPreference(readPreference).Find(filter).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();

            return await _dbSet.WithReadPreference(readPreference).Find(filter).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
        }

        var fieldList = new List<ProjectionDefinition<TEntity>>();
        for (int i = 0; i < field.Length; i++)
        {
            fieldList.Add(Builders<TEntity>.Projection.Include(field[i].ToString()));
        }
        var projection = Builders<TEntity>.Projection.Combine(fieldList);
        fieldList?.Clear();

        if (sort == null)
            return await _dbSet.WithReadPreference(readPreference).Find(filter).Project<TEntity>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();

        return await _dbSet.WithReadPreference(readPreference).Find(filter).Sort(sort).Project<TEntity>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
    }

    #endregion

    #region Protected Methods

    protected ReadPreference GetReadPreference(bool readFromPrimary)
    {
        if (readFromPrimary)
            return ReadPreference.PrimaryPreferred;
        else
            return ReadPreference.SecondaryPreferred;
    }

    #endregion
}

Unity UGUI的PhysicsRayc可變化、可擴(kuò)展aster (物理射線檢測(cè))組件的介紹及使用,numpy

工作單元:UnitOfWork

在實(shí)際項(xiàng)目中,在對(duì)多個(gè)Repository操作之后,我們希望有一個(gè)統(tǒng)一的提交操作來(lái)實(shí)現(xiàn)事務(wù)的原子性。因此,我們可以有一個(gè)UnitOfWork來(lái)作為代理:

public class UnitOfWork : IUnitOfWork
{
    private readonly IMongoDbContext _context;

    public UnitOfWork(IMongoDbContext context)
    {
        _context = context;
    }

    public bool SaveChanges(IClientSessionHandle session)
    {
        return _context.Commit(session) > 0;
    }

    public async Task<bool> SaveChangesAsync(IClientSessionHandle session)
    {
        return await _context.CommitAsync(session) > 0;
    }

    public IClientSessionHandle BeginTransaction()
    {
        return _context.StartSession();
    }

    public async Task<IClientSessionHandle> BeginTransactionAsync()
    {
        return await _context.StartSessionAsync();
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}

封裝注入:ServiceCollectionExtensions

?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-828365.html

到了這里,關(guān)于Unity UGUI的PhysicsRayc可變化、可擴(kuò)展aster (物理射線檢測(cè))組件的介紹及使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Unity UGUI的PhysicsRaycaster (物算法能力可視化理射線檢測(cè))組件的介紹及使用

    Outline(描邊)組件是Unity UGUI中的一種特效組件,用于給UI元素添加描邊效果。通過設(shè)置描邊的顏色、寬度和模糊程度,可以使UI元素在視覺上更加突出。 Outline(描邊)組件通過在UI元素周圍繪制多個(gè)相同的UI元素,并設(shè)置不同的顏色和大小,從而實(shí)現(xiàn)描邊的效果。描邊的寬度和模糊

    2024年02月07日
    瀏覽(21)
  • Unity UG算法能力可視化UI的PhysicsRaycaster (物理射線檢測(cè))組件的介紹及使用

    PhysicsRaycaster是Unity UGUI中的一個(gè)組件,用于在UI元素上進(jìn)行物理射線檢測(cè)。它可以檢測(cè)鼠標(biāo)或觸摸事件是否發(fā)生在UI元素上,并將事件傳遞給相應(yīng)的UI元素。 PhysicsRaycaster通過發(fā)射一條射線來(lái)檢測(cè)UI元素。當(dāng)射線與UI元素相交時(shí),PhysicsRaycaster會(huì)將事件傳遞給相應(yīng)的UI元素。 Event

    2024年01月20日
    瀏覽(50)
  • Unity UGUI的PhysicsRaycaster (物理射相當(dāng)于利用泛型函數(shù)保存了類型信息線檢測(cè))組件的介紹及使用

    這是在Datadog公司任職的Kevin Gosse大佬使用C#編寫.NET分析器的系列文章之一,在國(guó)內(nèi)只有很少很少的人了解和研究.NET分析器,它常被用于APM(應(yīng)用性能診斷)、IDE、診斷工具中,比如Datadog的APM,Visual Studio的分析器以及Rider和Reshaper等等。之前只能使用C++編寫,自從.NET NativeAOT發(fā)

    2024年01月22日
    瀏覽(27)
  • Unity  SteamVR 2.x  UGUI射線交互 +物品射線點(diǎn)擊+物品抓起(超級(jí)簡(jiǎn)單)

    Unity SteamVR 2.x UGUI射線交互 +物品射線點(diǎn)擊+物品抓起(超級(jí)簡(jiǎn)單)

    剛開始先查看了其他道友的方案:1.Unity使用SteamVR2.0實(shí)現(xiàn)基本功能(瞬移,抓取物品,射線點(diǎn)擊,UI交互等)_貪小心的博客-CSDN博客_unity steam vr 2.【Steam VR 2.0】5.射線操作UGUI-射線點(diǎn)擊物體_恩博同學(xué)的博客-CSDN博客_htc steamvr 射線點(diǎn)擊ui 嗯。。。試著嘗試了一下,不是很好用,于是乎記

    2023年04月25日
    瀏覽(23)
  • Unity UGUI的GraphicRaycaster(射線投射)組件的介紹及使用

    GraphicRaycaster是Unity UGUI系統(tǒng)中的一個(gè)組件,用于處理射線投射事件。它可以將射線投射到UI元素上,并檢測(cè)是否有UI元素被點(diǎn)擊或觸摸到。 GraphicRaycaster通過射線投射的方式來(lái)檢測(cè)UI元素的點(diǎn)擊事件。當(dāng)用戶點(diǎn)擊屏幕或觸摸屏幕時(shí),GraphicRaycaster會(huì)發(fā)射一條射線,然后檢測(cè)射線是

    2024年02月15日
    瀏覽(97)
  • unity-2D游戲地面檢測(cè) 三射線檢測(cè)

    unity-2D游戲地面檢測(cè) 三射線檢測(cè)

    ? ? 2D游戲中跳躍是不可或缺的功能,要實(shí)現(xiàn)跳躍功能,就必須進(jìn)行地面檢測(cè)!常規(guī)方法是使用一根往角色下方延伸的射線檢測(cè),但是這種方法在一些復(fù)雜不規(guī)則的地面效果通常不盡人意。通過增加射線數(shù)量,即可完善這種方法的不足,達(dá)到在復(fù)雜地面也能正確檢測(cè)角色是否

    2024年02月15日
    瀏覽(22)
  • Unity 射線檢測(cè)

    Unity 射線檢測(cè)

    在Unity中,射線檢測(cè)(Raycasting)是一種常用的技術(shù),用于檢測(cè)射線是否與場(chǎng)景中的物體相交。這在游戲開發(fā)中用于實(shí)現(xiàn)點(diǎn)擊物體、射線武器的碰撞檢測(cè)、角色與環(huán)境的交互等方面非常有用。 定義:表示從一個(gè)點(diǎn)沿著特定方向延伸的虛擬線段 屬性: direction 射線的方向。 orig

    2024年02月13日
    瀏覽(21)
  • Unity之射線檢測(cè)

    Unity之射線檢測(cè)

    目錄 ??一、射線檢測(cè)原理 ??1.2、實(shí)現(xiàn)實(shí)例? ??二、導(dǎo)航 ??2.1 導(dǎo)航網(wǎng)格的使用 ??2.2 創(chuàng)建角色,在地形上移動(dòng) ??2.3 動(dòng)態(tài)障礙物? ??2.4 網(wǎng)格鏈接? ??2.5 自定義網(wǎng)格鏈接? ??2.6 區(qū)域 不知道大家有沒有玩過紅色警戒?—— 一款即時(shí)戰(zhàn)略游戲,和罪惡都市一樣小編小學(xué)的時(shí)

    2024年01月20日
    瀏覽(22)
  • Unity---2d射線檢測(cè)

    Unity---2d射線檢測(cè)

    目錄 1.目標(biāo)物體加對(duì)應(yīng)的collider碰撞體 ?2.調(diào)節(jié)ProjectSetting里的time 幀速 3.LayerMask設(shè)置 4.避坑代碼 1.目標(biāo)物體加對(duì)應(yīng)的collider碰撞體 ?2.調(diào)節(jié)ProjectSetting里的time 幀速 ??按需使用 3.LayerMask設(shè)置 Layers通常被攝像機(jī)用來(lái)渲染部分場(chǎng)景,和燈光照射部分場(chǎng)景使用。但是它們也可以用來(lái)

    2024年02月11日
    瀏覽(26)
  • Unity 的射線檢測(cè)

    Unity 的射線檢測(cè)

    Unity版本2020.3.32f1c1 目錄 Ray RaycastHit Physics.Raycast() RaycastHit[] ??Layer 應(yīng)用 1.對(duì)Bad層級(jí)的物體進(jìn)行著色 2.從相機(jī)發(fā)射射線與地面進(jìn)行射線交互 3.運(yùn)動(dòng)的物體在場(chǎng)景中進(jìn)行避障 總結(jié) 參考資料 原理是發(fā)射一條射線,傳入起始點(diǎn)和起始方向當(dāng)做射線的起點(diǎn)和方向。 在OnDrawGizmos()函數(shù)中

    2024年02月07日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包